[
  {
    "path": ".gitignore",
    "content": "*$py.class\n*,cover\n*.egg\n*.egg-info/\n*.log\n*.manifest\n*.mo\n*.pot\n*.py[co]\n*.py[cod]\n*.so\n*.spec\n*/.DS_Store\n*~\n.DS_Store\n._.DS_Store\n.Python\n.cache\n.coverage\n.coverage.*\n.eggs/\n.env\n.idea\n*/.idea\n_pycache__/\nbuild/\n*.npy\n.vscode/\n*.pkl\nmodel_dir/\n.ipynb_checkpoints/\n@*\noutput/\n*data/"
  },
  {
    "path": "Experiments/AGCRN/AGCRN.py",
    "content": "import os\nimport GPUtil\nimport torch\nimport argparse\nimport configparser\n\nfrom datetime import datetime\nfrom UCTB.model.AGCRN import AGCRN\nfrom UCTB.utils.utils_AGCRN import Trainer\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.utils.utils_AGCRN import get_dataloader_AGCRN\nfrom UCTB.evaluation import metric\n\n# Is GPU available\ndeviceIDs = GPUtil.getAvailable(order='last', limit=8, maxLoad=1, maxMemory=0.2,\n                                includeNan=False, excludeID=[], excludeUUID=[])\nif len(deviceIDs) == 0:\n    current_device = '-1'\nelse:\n    current_device = str(deviceIDs[0])\nDEVICE = 'cuda:{}'.format(current_device)\n\n#parser\nargs = argparse.ArgumentParser(description='arguments')\nargs.add_argument('--mode', default='train', type=str)\nargs.add_argument('--debug', default='False', type=eval)\nargs.add_argument('--model', default='AGCRN', type=str)\nargs.add_argument('--cuda', default=True, type=bool)\n\nDATASETPATH = os.path.abspath('.')+'/params.conf'\n\n#get configuration\nconfig = configparser.ConfigParser()\nconfig.read(DATASETPATH)\n#device\nargs.add_argument('--device', default=DEVICE, type=str, help='indices of GPUs')\n#data\nargs.add_argument('--lag', default=config['data']['lag'], type=int)\nargs.add_argument('--horizon', default=config['data']['horizon'], type=int)\nargs.add_argument('--num_nodes', default=config['data']['num_nodes'], type=int)\nargs.add_argument('--tod', default=config['data']['tod'], type=eval)\nargs.add_argument('--normalize', default=\"Zscore\", type=str)\nargs.add_argument(\n    '--column_wise', default=config['data']['column_wise'], type=eval)\nargs.add_argument('--default_graph',\n                  default=config['data']['default_graph'], type=eval)\n#model\nargs.add_argument(\n    '--input_dim', default=config['model']['input_dim'], type=int)\nargs.add_argument(\n    '--output_dim', default=config['model']['output_dim'], type=int)\nargs.add_argument(\n    '--embed_dim', default=config['model']['embed_dim'], type=int)\nargs.add_argument(\n    '--rnn_units', default=config['model']['rnn_units'], type=int)\nargs.add_argument(\n    '--num_layers', default=config['model']['num_layers'], type=int)\nargs.add_argument('--cheb_k', default=config['model']['cheb_order'], type=int)\n#train\nargs.add_argument(\n    '--loss_func', default=config['train']['loss_func'], type=str)\nargs.add_argument('--seed', default=config['train']['seed'], type=int)\nargs.add_argument(\n    '--batch_size', default=config['train']['batch_size'], type=int)\nargs.add_argument('--epochs', default=config['train']['epochs'], type=int)\nargs.add_argument('--lr_init', default=config['train']['lr_init'], type=float)\nargs.add_argument('--lr_decay', default=config['train']['lr_decay'], type=eval)\nargs.add_argument('--lr_decay_rate',\n                  default=config['train']['lr_decay_rate'], type=float)\nargs.add_argument('--lr_decay_step',\n                  default=config['train']['lr_decay_step'], type=str)\nargs.add_argument(\n    '--early_stop', default=config['train']['early_stop'], type=eval)\nargs.add_argument('--early_stop_patience',\n                  default=config['train']['early_stop_patience'], type=int)\nargs.add_argument(\n    '--grad_norm', default=config['train']['grad_norm'], type=eval)\nargs.add_argument('--max_grad_norm',\n                  default=config['train']['max_grad_norm'], type=int)\nargs.add_argument('--teacher_forcing', default=False, type=bool)\n#args.add_argument('--tf_decay_steps', default=2000, type=int, help='teacher forcing decay steps')\nargs.add_argument('--real_value', default=config['train']['real_value'],\n                  type=eval, help='use real value for loss calculation')\n#test\nargs.add_argument(\n    '--mae_thresh', default=config['test']['mae_thresh'], type=eval)\nargs.add_argument(\n    '--mape_thresh', default=config['test']['mape_thresh'], type=float)\n#log\nargs.add_argument('--log_dir', default='./', type=str)\nargs.add_argument('--log_step', default=config['log']['log_step'], type=int)\nargs.add_argument('--plot', default=config['log']['plot'], type=eval)\n\n# data loader parameters\nargs.add_argument(\"--dataset\", default='Bike', type=str,\n                  help=\"configuration file path\")\nargs.add_argument(\"--city\", default='NYC', type=str)\nargs.add_argument(\"--closeness_len\", default=6, type=int)\nargs.add_argument(\"--period_len\", default=7, type=int)\nargs.add_argument(\"--trend_len\", default=4, type=int)\nargs.add_argument(\"--data_range\", default=\"all\", type=str)\nargs.add_argument(\"--train_data_length\", default=\"all\", type=str)\nargs.add_argument(\"--test_ratio\", default=0.1, type=float)\nargs.add_argument(\"--MergeIndex\", default=1, type=int)\nargs.add_argument(\"--MergeWay\", default=\"sum\", type=str)\n\nargs = args.parse_args()\n\n# loading data\ndata_loader = NodeTrafficLoader(dataset=args.dataset, city=args.city,\n                                data_range=args.data_range, train_data_length=args.train_data_length,\n                                test_ratio=float(args.test_ratio),\n                                closeness_len=args.closeness_len,\n                                period_len=args.period_len,\n                                trend_len=args.trend_len,\n                                normalize=args.normalize,\n                                MergeIndex=args.MergeIndex,\n                                MergeWay=args.MergeWay)\n\nargs.num_nodes = data_loader.station_number\n\n#load dataset\ntrain_loader, val_loader, test_loader = get_dataloader_AGCRN(data_loader,\n                                                                     tod=args.tod, batchsize=args.batch_size, dow=False,\n                                                                     weather=False, single=False)\n\n\n#model build\nmodel = AGCRN(args.num_nodes,args.input_dim,args.rnn_units,args.output_dim,args.horizon,args.num_layers,args.default_graph,args.embed_dim,args.cheb_k)\nmodel = model.to(args.device)\n\n\n#config log path\ncurrent_time = datetime.now().strftime('%Y%m%d%H%M%S')\ncurrent_dir = os.path.dirname(os.path.realpath(__file__))\nlog_dir = os.path.join(current_dir, 'model_dir', \"{}_{}_{}_{}_{}_{}\".format(\n    args.dataset, args.city, args.MergeIndex, args.closeness_len, args.period_len, args.trend_len))\nif not os.path.exists(log_dir):\n    os.makedirs(log_dir)\nprint(\"log_dir:\", log_dir)\nargs.log_dir = log_dir\n\n#Train Or Test\ntrainer = Trainer(model, train_loader, val_loader, test_loader,  args)\nif args.mode == 'train':\n    # Train\n    trainer.train()\n\nmodel.load_state_dict(torch.load(os.path.join(log_dir, \"best_model.pth\")))\n\nprint(\"Load saved model\")\n\n# Test\ntest_prediction = trainer.test(\n    model, trainer.args, test_loader, trainer.logger)\ntest_prediction = data_loader.normalizer.inverse_transform(test_prediction)\ny_true = data_loader.normalizer.inverse_transform(data_loader.test_y)\ntest_rmse = metric.rmse(prediction=test_prediction.squeeze(), target=y_true.squeeze())\ntest_rmse = metric.rmse(prediction=test_prediction.squeeze(), target=data_loader.test_y.squeeze())\n\nprint('Test RMSE', test_rmse)\n"
  },
  {
    "path": "Experiments/AGCRN/Runner.py",
    "content": "import os\n\n#############################################\n# BenchMark Bike\n#############################################\n########### NYC ###########\n# os.system(\"python AGCRN.py --dataset Bike --city NYC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum\")\n\n# os.system(\"python AGCRN.py --dataset Bike --city NYC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum\")\n\n# os.system(\"python AGCRN.py --dataset Bike --city NYC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum\")\n\n\n# # ########### Chicago ###########\nos.system(\"python AGCRN.py --dataset Bike --city Chicago --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum\")\n\n# # # os.system(\"python AGCRN.py --dataset Bike --city Chicago --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum\")\n\n# os.system(\"python AGCRN.py --dataset Bike --city Chicago --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum\")\n\n\n# # ########### DC ###########\n# # # os.system(\"python AGCRN.py --dataset Bike --city DC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum\")\n\n# # # os.system(\"python AGCRN.py --dataset Bike --city DC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum\")\n\n# os.system(\"python AGCRN.py --dataset Bike --city DC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum\")\n\n\n\n# # ###############################################\n# # # BenchMark DiDi\n# # ###############################################\n# # ############# Xian #############\n# # # os.system(\"python AGCRN.py --dataset DiDi --city Xian --MergeIndex 3 --MergeWay sum\")\n\n# # # os.system(\"python AGCRN.py --dataset DiDi --city Xian --MergeIndex 6 --MergeWay sum\")\n\n# os.system(\"python AGCRN.py --dataset DiDi --city Xian --MergeIndex 12 --MergeWay sum\")\n\n# # ############# Chengdu #############\n# # # os.system(\"python AGCRN.py --dataset DiDi --city Chengdu --MergeIndex 3 --MergeWay sum\")\n\n# # # os.system(\"python AGCRN.py --dataset DiDi --city Chengdu --MergeIndex 6 --MergeWay sum\")\n\n# os.system(\"python AGCRN.py --dataset DiDi --city Chengdu --MergeIndex 12 --MergeWay sum\")\n\n\n\n# # ###############################################\n# # # BenchMark Metro\n# # ###############################################\n# # ############# Chongqing #############\n# # # os.system(\"python AGCRN.py --dataset Metro --city Chongqing --MergeIndex 3 --MergeWay sum\")\n\n# # # os.system(\"python AGCRN.py --dataset Metro --city Chongqing --MergeIndex 6 --MergeWay sum\")\n\n#os.system(\"python AGCRN.py --dataset Metro --city Chongqing --MergeIndex 12 --MergeWay sum\")\n\n\n# # ############# Shanghai #############\n# # # os.system(\"python AGCRN.py --dataset Metro --city Shanghai --MergeIndex 3 --MergeWay sum\")\n\n# # # os.system(\"python AGCRN.py --dataset Metro --city Shanghai --MergeIndex 6 --MergeWay sum\")\n\n# os.system(\"python AGCRN.py --dataset Metro --city Shanghai --MergeIndex 12 --MergeWay sum\")\n\n\n\n# # ###############################################\n# # # BenchMark ChargeStation\n# # ###############################################\n\n# # # os.system(\"python AGCRN.py --dataset ChargeStation --city Beijing --MergeIndex 1 --MergeWay max\")\n\n# os.system(\"python AGCRN.py --dataset ChargeStation --city Beijing --MergeIndex 2 --MergeWay max\")\n\n\n\n\n# # ###############################################\n# # # BenchMark METR-LA\n# # ###############################################\n\n# # # os.system(\"python AGCRN.py --dataset METR --city LA --MergeIndex 3 --MergeWay average\")\n\n# # # os.system(\"python AGCRN.py --dataset METR --city LA --MergeIndex 6 --MergeWay average\")\n\n# os.system(\"python AGCRN.py --dataset METR --city LA --MergeIndex 12 --MergeWay average\")\n\n\n# # ###############################################\n# # # BenchMark PEMS-BAY\n# # ###############################################\n# # # os.system(\"python AGCRN.py --dataset PEMS --city BAY --MergeIndex 3 --MergeWay average\")\n\n# # # os.system(\"python AGCRN.py --dataset PEMS --city BAY --MergeIndex 6 --MergeWay average\")\n\n# os.system(\"python AGCRN.py --dataset PEMS --city BAY --MergeIndex 12 --MergeWay average\")\n"
  },
  {
    "path": "Experiments/AGCRN/params.conf",
    "content": "[data]\nnum_nodes =717 \nlag = 12\nhorizon = 1\nval_ratio = 0.2\ntest_ratio = 0.2\ntod = False\nnormalizer = std\ncolumn_wise = False\ndefault_graph = True\n\n[model]\ninput_dim = 1\noutput_dim = 1\nembed_dim = 10\nrnn_units = 64\nnum_layers = 2\ncheb_order = 2\n\n[train]\nloss_func = mae\nseed = 10\nbatch_size = 16\nepochs = 1500\nlr_init = 0.003\nlr_decay = False\nlr_decay_rate = 0.3\nlr_decay_step = 5,20,40,70\nearly_stop = False\nearly_stop_patience = 15\ngrad_norm = False\nmax_grad_norm = 5\nreal_value = True\n\n[test]\nmae_thresh = None\nmape_thresh = 0.\n\n[log]\nlog_step = 20\nplot = False"
  },
  {
    "path": "Experiments/ARIMA/ARIMA.py",
    "content": "import numpy as np\nimport argparse\nfrom tqdm import tqdm\nfrom UCTB.model import ARIMA\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess import SplitData\nimport os\n\nimport warnings\n\nwarnings.filterwarnings('ignore')\n\n\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\n# data source\nparser.add_argument('--dataset', default=' ', type=str)\nparser.add_argument('--city', default=None)\nparser.add_argument('--MergeIndex', default=3)\nparser.add_argument('--MergeWay', default='sum',type=str)\nparser.add_argument('--test_ratio', default=0.1, type=float)\n\n# network parameter\nparser.add_argument('--CT', default='168', type=int)\n\nparser.add_argument('--ar', default='3', type=int)\nparser.add_argument('--d', default='0', type=int)\nparser.add_argument('--ma', default='1', type=int)\n\nparser.add_argument('--sar', default='0', type=int)\nparser.add_argument('--sd', default='0', type=int)\nparser.add_argument('--sma', default='0', type=int)\nparser.add_argument('--sp', default='0', type=int)\n\n\nparser.add_argument('--DataRange', default=\"all\")\nparser.add_argument('--TrainDays', default=\"all\")\n\n\nargs = vars(parser.parse_args())\n\n\ndata_loader = NodeTrafficLoader(dataset=args['dataset'], city=args['city'],\n                                data_range=args['DataRange'], train_data_length=args['TrainDays'],\n                                test_ratio=args['test_ratio'],\n                                closeness_len=int(args['CT']), period_len=0, trend_len=0,\n                                with_lm=False, with_tpe=False, normalize=False,MergeIndex=args['MergeIndex'],\n                                MergeWay=args['MergeWay'])\n                                \n\ntrain_closeness, val_closeness = SplitData.split_data(data_loader.train_closeness, [0.9, 0.1])\ntrain_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\n\nval_prediction_collector = []\ntest_prediction_collector = []\n\n\nprint('*************************************************************')\n\nfor i in tqdm(range(data_loader.station_number)):\n\n    try:\n        model_obj = ARIMA(time_sequence=train_closeness[:, i, -1, 0],\n                          order=[args['ar'], args['d'], args['ma']],\n                          seasonal_order=[args['sar'], args['sd'], args['sma'], args['sp']])\n\n        val_prediction = model_obj.predict(\n            time_sequences=val_closeness[:, i, :, 0], forecast_step=1)\n        test_prediction = model_obj.predict(\n            time_sequences=data_loader.test_closeness[:, i, :, 0], forecast_step=1)\n\n    except Exception as e:\n        print('Converge failed with error', e)\n        print('Using last as prediction')\n\n        val_prediction = val_closeness[:, i, -1:, :]\n        test_prediction = data_loader.test_closeness[:, i, -1:, :]\n\n    val_prediction_collector.append(val_prediction)\n    test_prediction_collector.append(test_prediction)\n\n    print('Station', i, metric.rmse(test_prediction,\n                                    data_loader.test_y[:, i:i+1]))\n\n\nval_prediction_collector = np.concatenate(val_prediction_collector, axis=-2)\ntest_prediction_collector = np.concatenate(test_prediction_collector, axis=-2)\n\nval_rmse = metric.rmse(val_prediction_collector, val_y)\ntest_rmse = metric.rmse(test_prediction_collector,\n                        data_loader.test_y)\n\nprint(args['dataset'], args['city'], 'val_rmse', val_rmse)\nprint(args['dataset'], args['city'],'test_rmse', test_rmse)\n\n\nprint('*************************************************************')\n"
  },
  {
    "path": "Experiments/ARIMA/ARIMA_Parallel.py",
    "content": "import os\nimport numpy as np\nimport argparse\n\nfrom UCTB.model import ARIMA\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\nfrom UCTB.utils import multiple_process\n\n\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\n# data source\nparser.add_argument('--Dataset', default='Bike')\nparser.add_argument('--City', default='NYC')\n# network parameter\nparser.add_argument('--CT', default='24', type=int)\n\nparser.add_argument('--ar', default='6', type=int)\nparser.add_argument('--d', default='0', type=int)\nparser.add_argument('--ma', default='1', type=int)\n\nparser.add_argument('--sar', default='0', type=int)\nparser.add_argument('--sd', default='0', type=int)\nparser.add_argument('--sma', default='0', type=int)\nparser.add_argument('--sp', default='0', type=int)\n\nparser.add_argument('--DataRange', default='All')\nparser.add_argument('--TrainDays', default='365')\n\nargs = vars(parser.parse_args())\n\ndata_loader = NodeTrafficLoader(dataset=args['Dataset'], city=args['City'],\n                                closeness_len=int(args['CT']), period_len=0, trend_len=0,\n                                data_range=args['DataRange'], train_data_length=args['TrainDays'],\n                                with_lm=False, with_tpe=False, normalize=False)\n\n\ndef task(share_queue, locker, data, parameters):\n\n    print('Child process %s with pid %s' % (parameters[0], os.getpid()))\n\n    val_collector = {}\n    test_collector = {}\n\n    for i in data:\n\n        print('Child process %s' % (parameters[0]),\n              args['Dataset'], args['City'], 'Station', i, 'total', data_loader.station_number)\n\n        try:\n            model_obj = ARIMA(time_sequence=data_loader.train_closeness[:, i, -1, 0],\n                              order=[args['ar'], args['d'], args['ma']],\n                              seasonal_order=[args['sar'], args['sd'], args['sma'], args['sp']])\n\n            test_prediction = model_obj.predict(time_sequences=data_loader.test_closeness[:, i, :, 0], forecast_step=1)\n\n            del model_obj\n\n        except Exception as e:\n            print('Converge failed with error', e)\n            print('Using last as prediction')\n\n            test_prediction = data_loader.test_closeness[:, i, -1:, :]\n\n        test_collector[i] = test_prediction\n\n        print('Station', i, metric.rmse(test_prediction, data_loader.test_y[:, i:i + 1]))\n\n    locker.acquire()\n    share_queue.put([val_collector, test_collector])\n    locker.release()\n\n\ndef reduce_fn(a, b):\n    a[0].update(b[0])\n    a[1].update(b[1])\n    return a\n\n\nif __name__ == '__main__':\n\n    n_job = 8\n\n    result = multiple_process(distribute_list=range(data_loader.station_number),\n                              partition_func=lambda data, i, n_job:\n                              [data[e] for e in range(len(data)) if e % n_job == i],\n                              task_func=task, n_jobs=n_job, reduce_func=reduce_fn, parameters=[])\n\n    test_rmse_collector = [e[1] for e in sorted(result[1].items(), key=lambda x: x[0])]\n\n    test_rmse_collector = np.concatenate(test_rmse_collector, axis=-2)\n\n    test_rmse = metric.rmse(test_rmse_collector, data_loader.test_y)\n\n    print(args['Dataset'], args['City'], 'test_rmse', test_rmse)"
  },
  {
    "path": "Experiments/ARIMA/RunnerARIMA.py",
    "content": "import os\nfrom tqdm import tqdm\n# dataset = [['Bike','NYC','all','365','sum','0.1'],['DiDi','Xian','all','all','sum','0.1'],\n# ['Metro','Chongqing','all','all','sum','0.1'],['ChargeStation','Beijing','all','all','max','0.1'],\n# ['METR','LA','all','all','average','0.2'],['PEMS','BAY','all','all','average','0.2']]\n# dataset = [['METR','LA','all','all','average','0.2'],['PEMS','BAY','all','all','average','0.2']]\n\n# dataset = [['Bike', 'NYC', '0.125', '60', 'sum', '0.1'], ['Bike', 'Chicago', '0.125', '60', 'sum', '0.1'], ['Bike', 'DC', '0.125', '60', 'sum', '0.1'],\n#            ['DiDi', 'Xian', 'all', 'all', 'sum', '0.1'], ['DiDi', 'Chengdu', 'all', 'all', 'sum', '0.1'],\n#            ['Metro', 'Chongqing', 'all', 'all', 'sum', '0.1'], ['Metro', 'Shanghai', 'all', 'all', 'sum', '0.1'],\n#            ['METR', 'LA', 'all', 'all', 'average', '0.2'], ['PEMS', 'BAY', 'all', 'all', 'average', '0.2']]\n\ndataset = [['DiDi', 'Xian_Street', 'all', 'all', 'sum', '0.1'], ['DiDi', 'Chengdu_Street', 'all', 'all', 'sum', '0.1']]\n\n\n\nwith open(\"ARIMAresult3.txt\",\"w\") as fp:\n\n    for index in tqdm(range(len(dataset))):\n\n        fp.write(\"*********************************************************\\n\")\n        fp.write(\"Processing city----------------{}---using ARIMA-------MergeIndex 12 --\".format(dataset[index]))\n        f_tmp = os.popen(\"python -W ignore ARIMA.py --dataset {} --city {} --MergeIndex 12 --DataRange {} --TrainDays {} --MergeWay {} --test_ratio {}\".format(dataset[index][0],dataset[index][1],dataset[index][2],dataset[index][3],dataset[index][4],dataset[index][5]), \"r\")\n        # to record ouput\n        fp.write(f_tmp.read()) \n        fp.flush()\n        f_tmp.close()\n\n    fp.write(\"\\n\")\n"
  },
  {
    "path": "Experiments/ARIMA/trials.py",
    "content": "import os\n\nfrom UCTB.utils import multiple_process\n\n\ndef task_func(share_queue, locker, data, parameters):\n\n    print('Child process %s with pid %s' % (parameters[0], os.getpid()))\n\n    for task in data:\n        print('Child process', parameters[0], 'running', task)\n        exec_str = 'python ARIMA.py --Dataset %s --City %s ' % (task[0], task[1])\n        if task[2] != '':\n            exec_str += task[2]\n        os.system(exec_str)\n\n    locker.acquire()\n    share_queue.put(None)\n    locker.release()\n\n\nif __name__ == '__main__':\n\n    task_list = [\n        ['Bike', 'NYC', ''],\n        ['Bike', 'Chicago', ''],\n        ['Bike', 'DC', ''],\n        ['Metro', 'Chongqing', ''],\n        ['Metro', 'Shanghai', ''],\n        ['DiDi', 'Chengdu', ''],\n        ['DiDi', 'Xian', ''],\n        ['ChargeStation', 'Beijing', '']\n    ]\n\n    n_jobs = 1\n\n    multiple_process(distribute_list=task_list,\n                     partition_func=lambda data, i, n_job: [data[e] for e in range(len(data)) if e % n_job == i],\n                     task_func=task_func, n_jobs=n_jobs,\n                     reduce_func=lambda x,y: None, parameters=[])\n\n"
  },
  {
    "path": "Experiments/ASTGCN/ASTGCN.py",
    "content": "import torch\nimport os\nimport GPUtil\nimport argparse\nimport configparser\n\nfrom UCTB.model.ASTGCN import make_model\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.utils.utils_ASTGCN import load_data, train_main, predict_main\n\nfrom UCTB.preprocess.GraphGenerator import scaled_Laplacian_ASTGCN\n\n\nparser = argparse.ArgumentParser()\nparser.add_argument(\"--config\", default='./configurations/PEMS04_astgcn.conf', type=str,\n                    help=\"configuration file path\")\nparser.add_argument(\"--dataset\", default='Bike', type=str,\n                    help=\"configuration file path\")\nparser.add_argument(\"--city\", default='NYC', type=str)\nparser.add_argument(\"--closeness_len\", default=6, type=int)\nparser.add_argument(\"--period_len\", default=7, type=int)\nparser.add_argument(\"--trend_len\", default=4, type=int)\nparser.add_argument(\"--data_range\", default=\"all\", type=str)\nparser.add_argument(\"--train_data_length\", default=\"all\", type=str)\nparser.add_argument(\"--test_ratio\", default=0.1, type=float)\nparser.add_argument(\"--MergeIndex\", default=1, type=int)\nparser.add_argument(\"--MergeWay\", default=\"sum\", type=str)\nargs = parser.parse_args()\n\n#config\nconfig = configparser.ConfigParser()\nprint('Read configuration file: %s' % (args.config))\nconfig.read(args.config)\ndata_config = config['Data']\ntraining_config = config['Training']\nadj_filename = data_config['adj_filename']\ngraph_signal_matrix_filename = data_config['graph_signal_matrix_filename']\nbatch_size = int(training_config['batch_size'])\nnum_of_hours = int(training_config['num_of_hours'])\ntime_strides = num_of_hours\nnb_chev_filter = int(training_config['nb_chev_filter'])\nnb_time_filter = int(training_config['nb_time_filter'])\nin_channels = int(training_config['in_channels'])\nnb_block = int(training_config['nb_block'])\nK = int(training_config['K'])\nloss_function = training_config['loss_function']\nmetric_method = training_config['metric_method']\nmissing_value = float(training_config['missing_value'])\nif config.has_option('Data', 'id_filename'):\n    id_filename = data_config['id_filename']\nelse:\n    id_filename = None\n# num_for_predict = int(data_config['num_for_predict'])\nnum_for_predict = 1\ndataset_name = \"{}_{}_{}\".format(args.dataset, args.city, args.MergeIndex)\nmodel_name = training_config['model_name']\n\n# ctx = training_config['ctx']\n# os.environ[\"CUDA_VISIBLE_DEVICES\"] = ctx\ndeviceIDs = GPUtil.getAvailable(order='last', limit=8, maxLoad=1, maxMemory=0.7,\n                                includeNan=False, excludeID=[], excludeUUID=[])\nif len(deviceIDs) == 0:\n    current_device = \"cpu\"\nelse:\n    current_device = str(deviceIDs[0])\n\nUSE_CUDA = torch.cuda.is_available()\nDEVICE = torch.device('cuda:{}'.format(current_device))\nprint(\"CUDA:\", USE_CUDA, DEVICE)\n\n\nfolder_dir = '%s_channel_%d' % (model_name, in_channels)\nprint('folder_dir:', folder_dir)\nparams_path = os.path.join('model_dir', dataset_name, folder_dir)\nprint('params_path:', params_path)\n\n\n# loading data\nuctb_data_loader = NodeTrafficLoader(dataset=args.dataset, city=args.city,\n                                     data_range=args.data_range, train_data_length=args.train_data_length,\n                                     test_ratio=float(args.test_ratio),\n                                     closeness_len=args.closeness_len,\n                                     period_len=args.period_len,\n                                     trend_len=args.trend_len,\n                                     normalize=False,\n                                     MergeIndex=args.MergeIndex,\n                                     MergeWay=args.MergeWay)\n\n\n# Build Graph\ngraph_obj = GraphGenerator(graph='distance', data_loader=uctb_data_loader)\n\nnum_of_vertices = uctb_data_loader.station_number\nlen_input = uctb_data_loader.closeness_len + \\\n    uctb_data_loader.period_len + uctb_data_loader.trend_len\n\n\n#load data\ntrain_loader, train_target_tensor, val_loader, val_target_tensor, test_loader, test_target_tensor= load_data(\n    uctb_data_loader, DEVICE, batch_size)\nadj_mx = graph_obj.AM[0]\nL_tilde = scaled_Laplacian_ASTGCN(adj_mx)\n\n#build model\nnet = make_model(DEVICE, nb_block, in_channels, K, nb_chev_filter, nb_time_filter, time_strides, L_tilde,\n                 num_for_predict, len_input, num_of_vertices)\n\n#train\nbest_epoch = train_main(training_config, params_path, DEVICE, net, val_loader, train_loader, graph_signal_matrix_filename)\n\n# apply the best model and predict on the test set\ntest_prediction = predict_main(net, best_epoch, test_loader, test_target_tensor,\n                               params_path)\n\ntest_prediction = uctb_data_loader.normalizer.inverse_transform(test_prediction)\ny_truth = uctb_data_loader.normalizer.inverse_transform(uctb_data_loader.test_y)\ntest_rmse = metric.rmse(prediction=test_prediction,\n                        target=y_truth)\nprint('Test RMSE', test_rmse)\n"
  },
  {
    "path": "Experiments/ASTGCN/Runner.py",
    "content": "import os\n\n# #############################################\n# # BenchMark Bike\n# #############################################\n# ########### NYC ###########\n# # os.system(\"python ASTGCN.py --dataset Bike --city NYC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum\")\n\n# os.system(\"python ASTGCN.py --dataset Bike --city NYC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum\")\n\n# # os.system(\"python ASTGCN.py --dataset Bike --city NYC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum\")\n\n\n# # ########### Chicago ###########\n# # # os.system(\"python ASTGCN.py --dataset Bike --city Chicago --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum\")\n\n# os.system(\"python ASTGCN.py --dataset Bike --city Chicago --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum\")\n\n# # os.system(\"python ASTGCN.py --dataset Bike --city Chicago --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum\")\n\n\n# # ########### DC ###########\n# # # os.system(\"python ASTGCN.py --dataset Bike --city DC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum\")\n\n# os.system(\"python ASTGCN.py --dataset Bike --city DC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum\")\n\n# # os.system(\"python ASTGCN.py --dataset Bike --city DC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum\")\n\n\n\n# # ###############################################\n# # # BenchMark DiDi\n# # ###############################################\n# # ############# Xian #############\n# # # os.system(\"python ASTGCN.py --dataset DiDi --city Xian --MergeIndex 3 --MergeWay sum\")\n\n# os.system(\"python ASTGCN.py --dataset DiDi --city Xian --MergeIndex 6 --MergeWay sum\")\n\n# # os.system(\"python ASTGCN.py --dataset DiDi --city Xian --MergeIndex 12 --MergeWay sum\")\n\n# # ############# Chengdu #############\n# # # os.system(\"python ASTGCN.py --dataset DiDi --city Chengdu --MergeIndex 3 --MergeWay sum\")\n\n# os.system(\"python ASTGCN.py --dataset DiDi --city Chengdu --MergeIndex 6 --MergeWay sum\")\n\n# # os.system(\"python ASTGCN.py --dataset DiDi --city Chengdu --MergeIndex 12 --MergeWay sum\")\n\n\n\n# # ###############################################\n# # # BenchMark Metro\n# # ###############################################\n# # ############# Chongqing #############\n# # # os.system(\"python ASTGCN.py --dataset Metro --city Chongqing --MergeIndex 3 --MergeWay sum\")\n\n#os.system(\"python ASTGCN.py --dataset Metro --city Chongqing --MergeIndex 6 --MergeWay sum\")\n\n# # os.system(\"python ASTGCN.py --dataset Metro --city Chongqing --MergeIndex 12 --MergeWay sum\")\n\n\n# # ############# Shanghai #############\n# # # os.system(\"python ASTGCN.py --dataset Metro --city Shanghai --MergeIndex 3 --MergeWay sum\")\n\n# os.system(\"python ASTGCN.py --dataset Metro --city Shanghai --MergeIndex 6 --MergeWay sum\")\n\n# os.system(\"python ASTGCN.py --dataset Metro --city Shanghai --MergeIndex 12 --MergeWay sum\")\n\n\n\n# # ###############################################\n# # # BenchMark ChargeStation\n# # ###############################################\n\n# os.system(\"python ASTGCN.py --dataset ChargeStation --city Beijing --MergeIndex 1 --MergeWay max\")\n\n# os.system(\"python ASTGCN.py --dataset ChargeStation --city Beijing --MergeIndex 2 --MergeWay max\")\n\n\n\n# ###############################################\n# # BenchMark METR-LA\n# ###############################################\n\n# # os.system(\"python ASTGCN.py --dataset METR --city LA --MergeIndex 3 --MergeWay average\")\n\n# os.system(\"python ASTGCN.py --dataset METR --city LA --MergeIndex 6 --MergeWay average\")\n\n# os.system(\"python ASTGCN.py --dataset METR --city LA --MergeIndex 12 --MergeWay average\")\n\n\n# # ###############################################\n# # # BenchMark PEMS-BAY\n# # ###############################################\n# # # os.system(\"python ASTGCN.py --dataset PEMS --city BAY --MergeIndex 3 --MergeWay average\")\n\n# os.system(\"python ASTGCN.py --dataset PEMS --city BAY --MergeIndex 6 --MergeWay average\")\n\n# # os.system(\"python ASTGCN.py --dataset PEMS --city BAY --MergeIndex 12 --MergeWay average\")\n"
  },
  {
    "path": "Experiments/ASTGCN/configurations/METR_LA_astgcn.conf",
    "content": "[Data]\nadj_filename = ./data/METR_LA/distance_LA.csv\ngraph_signal_matrix_filename = ./data/METR_LA/METR_LA.npz\nnum_of_vertices = 207\npoints_per_hour = 12\nnum_for_predict = 12\nlen_input = 12\ndataset_name = METR_LA\n\n[Training]\nctx = 0\nin_channels = 1\nnb_block = 2\nK = 3\nnb_chev_filter = 64\nnb_time_filter = 64\nbatch_size = 16\nmodel_name = astgcn_r\ndataset_name = METR_LA\nnum_of_weeks = 0\nnum_of_days = 0\nnum_of_hours = 1\nstart_epoch = 0\nepochs = 100\nlearning_rate = 0.001\nloss_function = masked_mae\nmetric_method=mask\nmissing_value=0.0\n"
  },
  {
    "path": "Experiments/ASTGCN/configurations/PEMS04_astgcn.conf",
    "content": "[Data]\nadj_filename = ./data/PEMS04/distance.csv\ngraph_signal_matrix_filename = ./data/PEMS04/PEMS04.npz\nnum_of_vertices = 307\npoints_per_hour = 12\nnum_for_predict = 12\nlen_input = 12\ndataset_name = PEMS04\n\n[Training]\nctx = 0\nin_channels = 1\nnb_block = 2\nK = 3\nnb_chev_filter = 64\nnb_time_filter = 64\nbatch_size = 32\nmodel_name = astgcn_r\ndataset_name = PEMS04\nnum_of_weeks = 0\nnum_of_days = 0\nnum_of_hours = 1\nstart_epoch = 0\nepochs = 400\nlearning_rate = 0.001\nloss_function = mse\nmetric_method = unmask\nmissing_value=0.0\n"
  },
  {
    "path": "Experiments/ASTGCN/configurations/PEMS08_astgcn.conf",
    "content": "[Data]\nadj_filename = ../data/PEMS08/PEMS08.csv\ngraph_signal_matrix_filename = ../data/PEMS08/PEMS08.npz\nnum_of_vertices = 170\npoints_per_hour = 12\nnum_for_predict = 12\nlen_input = 12\ndataset_name = PEMS08\n\n[Training]\nctx = 3\nin_channels = 1\nnb_block = 2\nK = 3\nnb_chev_filter = 64\nnb_time_filter = 64\nbatch_size = 32\nmodel_name = astgcn_r\ndataset_name = PEMS08\nnum_of_weeks = 0\nnum_of_days = 0\nnum_of_hours = 1\nstart_epoch = 0\nepochs = 80\nlearning_rate = 0.001\nloss_function = mse\nmetric_method = unmask\nmissing_value=0.0"
  },
  {
    "path": "Experiments/CustomizedDemo/Runner_topk.py",
    "content": "import os\nimport numpy as np\nimport heapq\n\n#############################################\n# BenchMark Metro Shangahi (topK graph demo)\n#############################################\n\nos.system('python STMeta_Obj_topk.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml '\n          '-p graph:TopK,MergeIndex:12')\n\nos.system('python STMeta_Obj_topk.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line-TopK,MergeIndex:12')\n          \n\n"
  },
  {
    "path": "Experiments/CustomizedDemo/STMeta_Obj_topk.py",
    "content": "import os\nimport nni\nimport yaml\nimport argparse\nimport GPUtil\nimport numpy as np\nfrom UCTB.dataset import DataSet\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.time_utils import is_work_day_china, is_work_day_america\n\nfrom UCTB.preprocess import Normalizer, SplitData\n#####################################################################\n# argument parser\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\nparser.add_argument('-m', '--model', default='STMeta_v0.model.yml')\nparser.add_argument('-d', '--data', default='didi_chengdu.data.yml')\nparser.add_argument('-p', '--update_params', default='')\n\n# Parse params\nterminal_vars = vars(parser.parse_args())\nyml_files = [terminal_vars['model'], terminal_vars['data']]\nargs = {}\nfor yml_file in yml_files:\n    with open(yml_file, 'r') as f:\n        args.update(yaml.load(f))\n\nif len(terminal_vars['update_params']) > 0:\n    args.update({e.split(':')[0]: e.split(':')[1] for e in terminal_vars['update_params'].split(',')})\n    print({e.split(':')[0]: e.split(':')[1] for e in terminal_vars['update_params'].split(',')})\n\nnni_params = nni.get_next_parameter()\nnni_sid = nni.get_sequence_id()\nif nni_params:\n    args.update(nni_params)\n    args['mark'] += str(nni_sid)\n\n#####################################################################\n# Generate code_version\ncode_version = '{}_C{}P{}T{}_G{}_K{}L{}_F{}_{}'.format(args['model_version'],\n                                                   args['closeness_len'], args['period_len'],\n                                                   args['trend_len'],\n                                                   ''.join([e[0] for e in args['graph'].split('-')]),\n                                                   args['gcn_k'], args['gcn_layers'],int(args[\"MergeIndex\"])*5, args['mark'])\nmodel_dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'model_dir')\nmodel_dir_path = os.path.join(model_dir_path, args['group'])\n#####################################################################\n\ndata_loader = NodeTrafficLoader(dataset=args['dataset'], city=args['city'],\n                                data_range=args['data_range'], train_data_length=args['train_data_length'],\n                                test_ratio=0.1,\n                                closeness_len=args['closeness_len'],\n                                period_len=args['period_len'],\n                                trend_len=args['trend_len'],\n                                normalize=args['normalize'],\n                                with_tpe=True if args['st_method'] == 'gal_gcn' else False,\n                                workday_parser=is_work_day_america if args[\n                                    'dataset'] == 'Bike' else is_work_day_china,\n                                MergeIndex=args['MergeIndex'],\n                                MergeWay=\"max\" if args[\"dataset\"] == \"ChargeStation\" else \"sum\")\n\n\n# Call GraphGenerator to initialize and generate LM\nfrom topKGraph import topKGraph\ngraphBuilder = topKGraph(graph=args['graph'],\n                         data_loader=data_loader,\n                         threshold_distance=args['threshold_distance'],\n                         threshold_correlation=args['threshold_correlation'],\n                         threshold_interaction=args['threshold_interaction'],\n                         threshold_neighbour=args['threshold_neighbour'])\n\nprint(\"TimeFitness\",data_loader.dataset.time_fitness)\nprint(\"TimeRange\",data_loader.dataset.time_range)\n\nde_normalizer = None if args['normalize'] is False else data_loader.normalizer.min_max_denormal\n\ndeviceIDs = GPUtil.getAvailable(order='last', limit=8, maxLoad=1, maxMemory=0.7,\n                                includeNan=False, excludeID=[], excludeUUID=[])\n\nif len(deviceIDs) == 0:\n    current_device = '-1'\nelse:\n    if nni_params:\n        current_device = str(deviceIDs[int(nni_sid) % len(deviceIDs)])\n    else:\n        current_device = str(deviceIDs[0])\n\nSTMeta_obj = STMeta(num_node=data_loader.station_number,\n                    num_graph=graphBuilder.LM.shape[0],\n                    external_dim=data_loader.external_dim,\n                    closeness_len=args['closeness_len'],\n                    period_len=args['period_len'],\n                    trend_len=args['trend_len'],\n                    gcn_k=int(args.get('gcn_k', 0)),\n                    gcn_layers=int(args.get('gcn_layers', 0)),\n                    gclstm_layers=int(args['gclstm_layers']),\n                    num_hidden_units=args['num_hidden_units'],\n                    num_dense_units=args['num_filter_conv1x1'],\n                    # temporal attention parameters\n                    tpe_dim=data_loader.tpe_dim,\n                    temporal_gal_units=args.get('temporal_gal_units'),\n                    temporal_gal_num_heads=args.get('temporal_gal_num_heads'),\n                    temporal_gal_layers=args.get('temporal_gal_layers'),\n                    # merge parameters\n                    graph_merge_gal_units=args['graph_merge_gal_units'],\n                    graph_merge_gal_num_heads=args['graph_merge_gal_num_heads'],\n                    temporal_merge_gal_units=args['temporal_merge_gal_units'],\n                    temporal_merge_gal_num_heads=args['temporal_merge_gal_num_heads'],\n                    # network structure parameters\n                    st_method=args['st_method'],  # gclstm\n                    temporal_merge=args['temporal_merge'],  # gal\n                    graph_merge=args['graph_merge'],  # concat\n                    build_transfer=args['build_transfer'],\n                    lr=float(args['lr']),\n                    code_version=code_version,\n                    model_dir=model_dir_path,\n                    gpu_device=current_device)\n\nSTMeta_obj.build()\n\nprint(args['dataset'], args['city'], code_version)\nprint('Number of trainable variables', STMeta_obj.trainable_vars)\nprint('Number of training samples', data_loader.train_sequence_len)\n\n# # Training\nif args['train']:\n    STMeta_obj.fit(closeness_feature=data_loader.train_closeness,\n                   period_feature=data_loader.train_period,\n                   trend_feature=data_loader.train_trend,\n                   laplace_matrix=graphBuilder.LM,\n                   target=data_loader.train_y,\n                   external_feature=data_loader.train_ef,\n                   sequence_length=data_loader.train_sequence_len,\n                   output_names=('loss', ),\n                   evaluate_loss_name='loss',\n                   op_names=('train_op', ),\n                   batch_size=int(args['batch_size']),\n                   max_epoch=int(args['max_epoch']),\n                   validate_ratio=0.1,\n                   early_stop_method='t-test',\n                   early_stop_length=args['early_stop_length'],\n                   early_stop_patience=args['early_stop_patience'],\n                   verbose=True,\n                   save_model=True)\n\nSTMeta_obj.load(code_version)\n\nprediction = STMeta_obj.predict(closeness_feature=data_loader.test_closeness,\n                                period_feature=data_loader.test_period,\n                                trend_feature=data_loader.test_trend,\n                                laplace_matrix=graphBuilder.LM,\n                                target=data_loader.test_y,\n                                external_feature=data_loader.test_ef,\n                                output_names=('prediction', ),\n                                sequence_length=data_loader.test_sequence_len,\n                                cache_volume=int(args['batch_size']), )\n\ntest_prediction = prediction['prediction']\n\nif de_normalizer:\n    test_prediction = de_normalizer(test_prediction)\n    data_loader.test_y = de_normalizer(data_loader.test_y)\n\ntest_rmse, test_mape = metric.rmse(prediction=test_prediction, target=data_loader.test_y),\\\n                       metric.mape(prediction=test_prediction, target=data_loader.test_y, threshold=0)\n\n# Evaluate\nval_loss = STMeta_obj.load_event_scalar('val_loss')\n\nbest_val_loss = min([e[-1] for e in val_loss])\n\nif de_normalizer:\n    best_val_loss = de_normalizer(best_val_loss)\n\nprint('Best val result', best_val_loss)\nprint('Test result', test_rmse, test_mape)\n\ntime_consumption = [val_loss[e][0] - val_loss[e-1][0] for e in range(1, len(val_loss))]\ntime_consumption = sum([e for e in time_consumption if e < (min(time_consumption) * 10)]) / 3600\nprint('Converged using %.2f hour / %s epochs' % (time_consumption, STMeta_obj._global_step))\n\n\nif nni_params:\n    nni.report_final_result({\n        'default': best_val_loss,\n        'test-rmse': test_rmse,\n        'test-mape': test_mape\n    })\n"
  },
  {
    "path": "Experiments/CustomizedDemo/STMeta_v0.model.yml",
    "content": "# network structure parameters\nst_method: 'LSTM'\ntemporal_merge: 'gal'\ngraph_merge: 'gal'\n\n# gcn parameters\ngcn_k: 0\ngcn_layers: 1\ngclstm_layers: 1\n\n# LSTM units\nnum_hidden_units: 64\n# dense units\nnum_filter_conv1x1: 32\n\nbuild_transfer: False\n\n# merge parameters\ngraph_merge_gal_units: 64\ngraph_merge_gal_num_heads: 2\ntemporal_merge_gal_units: 64\ntemporal_merge_gal_num_heads: 2\n\nmodel_version: 'TMeta'"
  },
  {
    "path": "Experiments/CustomizedDemo/STMeta_v1.model.yml",
    "content": "# network structure parameters\nst_method: 'GCLSTM'\ntemporal_merge: 'gal'\ngraph_merge: 'gal'\n\n# gcn parameters\ngcn_k: 1\ngcn_layers: 1\ngclstm_layers: 1\n\n# LSTM units\nnum_hidden_units: 64\n# dense units\nnum_filter_conv1x1: 32\n\nbuild_transfer: False\n\n# merge parameters\ngraph_merge_gal_units: 64\ngraph_merge_gal_num_heads: 2\ntemporal_merge_gal_units: 64\ntemporal_merge_gal_num_heads: 2\n\nmodel_version: 'V1'"
  },
  {
    "path": "Experiments/CustomizedDemo/STMeta_v2.model.yml",
    "content": "# network structure parameters\nst_method: 'GCLSTM'\ntemporal_merge: 'concat'\ngraph_merge: 'gal'\n\n# gcn parameters\ngcn_k: 1\ngcn_layers: 1\ngclstm_layers: 1\n\n# LSTM units\nnum_hidden_units: 64\n# dense units\nnum_filter_conv1x1: 32\n\nbuild_transfer: False\n\n# merge parameters\ngraph_merge_gal_units: 64\ngraph_merge_gal_num_heads: 2\ntemporal_merge_gal_units: 64\ntemporal_merge_gal_num_heads: 2\n\nmodel_version: 'V2'"
  },
  {
    "path": "Experiments/CustomizedDemo/STMeta_v3.model.yml",
    "content": "# network structure parameters\nst_method: 'DCRNN'\ntemporal_merge: 'gal'\ngraph_merge: 'gal'\n\n# gcn parameters\ngcn_k: 1\ngcn_layers: 1\ngclstm_layers: 1\n\n# LSTM units\nnum_hidden_units: 64\n# dense units\nnum_filter_conv1x1: 32\n\n# temporal process params\ntemporal_gal_units: 32\ntemporal_gal_num_heads: 2\ntemporal_gal_layers: 4\n\nbuild_transfer: False\n\n# merge parameters\ngraph_merge_gal_units: 64\ngraph_merge_gal_num_heads: 2\ntemporal_merge_gal_units: 64\ntemporal_merge_gal_num_heads: 2\n\nmodel_version: 'V3'"
  },
  {
    "path": "Experiments/CustomizedDemo/metro_shanghai.data.yml",
    "content": "# dataset and city\ndataset: Metro\ncity: Shanghai\n\ncloseness_len: 6\nperiod_len: 7\ntrend_len: 4\n\ngraph: Distance-Correlation-Line\n\ndata_range: all\ntrain_data_length: all\n\nthreshold_distance: 5000\nthreshold_correlation: 0.7\nthreshold_interaction: 30\nthreshold_neighbour: 23\n\nnormalize: True\ntrain: True\n\nlr: 1e-5\nearly_stop_length: 200\nearly_stop_patience: 0.1\nmax_epoch: 20000\nbatch_size: 64\n\ngroup: Shanghai\nmark: BM"
  },
  {
    "path": "Experiments/CustomizedDemo/topKGraph.py",
    "content": "import heapq\nimport numpy as np\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n\n\nclass topKGraph(GraphGenerator):  # Init NodeTrafficLoader\n\n    def __init__(self,**kwargs):\n\n        super(topKGraph, self).__init__(**kwargs)\n        \n        for graph_name in kwargs['graph'].split('-'):\n            if graph_name.lower() == 'topk':\n                lat_lng_list = np.array([[float(e1) for e1 in e[2:4]]\n                                         for e in self.dataset.node_station_info])\n                # Handling\n                AM = self.neighbour_adjacent(lat_lng_list[self.traffic_data_index],\n                                        threshold=int(kwargs['threshold_neighbour']))\n                LM = self.adjacent_to_laplacian(AM)\n\n                if self.AM.shape[0] == 0:  # Make AM\n                    self.AM = np.array([AM], dtype=np.float32)\n                else:\n                    self.AM = np.vstack((self.AM, (AM[np.newaxis, :])))\n\n                if self.LM.shape[0] == 0:  # Make LM\n                    self.LM = np.array([LM], dtype=np.float32)\n                else:\n                    self.LM = np.vstack((self.LM, (LM[np.newaxis, :])))\n\n    def neighbour_adjacent(self, lat_lng_list, threshold):\n        adjacent_matrix = np.zeros([len(lat_lng_list), len(lat_lng_list)])\n        for i in range(len(lat_lng_list)):\n            for j in range(len(lat_lng_list)):\n                adjacent_matrix[i][j] = self.haversine(\n                    lat_lng_list[i][0], lat_lng_list[i][1], lat_lng_list[j][0], lat_lng_list[j][1])\n        dis_matrix = adjacent_matrix.astype(np.float32)\n\n        for i in range(len(dis_matrix)):\n            ind = heapq.nlargest(threshold, range(len(dis_matrix[i])), dis_matrix[i].take)\n            dis_matrix[i] = np.array([0 for _ in range(len(dis_matrix[i]))])\n            dis_matrix[i][ind] = 1\n        adjacent_matrix = (adjacent_matrix == 1).astype(np.float32)\n        return adjacent_matrix\n"
  },
  {
    "path": "Experiments/DCRNN/DCRNN.py",
    "content": "import os\nimport numpy as np\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import DCRNN\nfrom UCTB.evaluation import metric\n\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n\nclass my_data_loader(NodeTrafficLoader):\n\n    def __init__(self, **kwargs):\n\n        super(my_data_loader, self).__init__(**kwargs) \n        \n        # generate LM\n        graph_obj = GraphGenerator(graph=kwargs['graph'], data_loader=self)\n        self.AM = graph_obj.AM\n        self.LM = graph_obj.LM\n\n    def diffusion_matrix(self, filter_type='random_walk'):\n        def calculate_random_walk_matrix(adjacent_mx):\n            d = np.array(adjacent_mx.sum(1))\n            d_inv = np.power(d, -1).flatten()\n            d_inv[np.isinf(d_inv)] = 0.\n            d_mat_inv = np.diag(d_inv)\n            random_walk_mx = d_mat_inv.dot(adjacent_mx)\n            return random_walk_mx\n\n        diffusion_matrix = []\n        if filter_type == \"random_walk\":\n            diffusion_matrix.append(calculate_random_walk_matrix(self.AM[0]).T)\n        elif filter_type == \"dual_random_walk\":\n            diffusion_matrix.append(calculate_random_walk_matrix(self.AM[0]).T)\n            diffusion_matrix.append(calculate_random_walk_matrix(self.AM[0].T).T)\n        return np.array(diffusion_matrix, dtype=np.float32)\n\n\ndef param_parser():\n    import argparse\n    parser = argparse.ArgumentParser(description=\"Argument Parser\")\n    # data source\n    parser.add_argument('--Dataset', default='DiDi')\n    parser.add_argument('--City', default='Chengdu')\n    # network parameter\n    parser.add_argument('--CT', default='6', type=int)\n    parser.add_argument('--PT', default='7', type=int)\n    parser.add_argument('--TT', default='4', type=int)\n    parser.add_argument('--K', default='1', type=int)\n    parser.add_argument('--L', default='1', type=int)\n    parser.add_argument('--Graph', default='Distance-Correlation-Interaction')\n    parser.add_argument('--LSTMUnits', default='64', type=int)\n    parser.add_argument('--LSTMLayers', default='3', type=int)\n    # Training data parameters\n    parser.add_argument('--DataRange', default='All')\n    parser.add_argument('--TrainDays', default='365')\n    parser.add_argument('--test_ratio', default=0.1, type=float)\n    # Graph parameter\n    parser.add_argument('--TC', default='0', type=float)\n    parser.add_argument('--TD', default='1000', type=float)\n    parser.add_argument('--TI', default='500', type=float)\n    # training parameters\n    parser.add_argument('--Epoch', default='5000', type=int)\n    parser.add_argument('--Train', default='True')\n    parser.add_argument('--lr', default='5e-4', type=float)\n    parser.add_argument('--ESlength', default='50', type=int)\n    parser.add_argument('--patience', default='0.1', type=float)\n    parser.add_argument('--BatchSize', default='64', type=int)\n    # device parameter\n    parser.add_argument('--Device', default='0', type=str)\n    # version control\n    parser.add_argument('--Group', default='DebugGroup')\n    parser.add_argument('--CodeVersion', default='ST_MGCN_Debug')\n    # Merge parameter\n    parser.add_argument('--MergeIndex', default=6, type=int)\n    parser.add_argument('--MergeWay', default='sum', type=str)\n    return parser\n\n\nparser = param_parser()\nargs = parser.parse_args()\n\nmodel_dir = os.path.join('model_dir', args.City)\ncode_version = 'DCRNN_{}_K{}L{}_{}_F{}'.format(''.join([e[0] for e in args.Graph.split('-')]),\n                                           args.K, args.L, args.CodeVersion, int(args.MergeIndex)*5)\n\ndata_loader = my_data_loader(dataset=args.Dataset, city=args.City,\n                             test_ratio=float(args.test_ratio),\n                             data_range=args.DataRange, train_data_length=args.TrainDays,\n                             closeness_len=int(args.CT), period_len=int(args.PT), trend_len=int(args.TT),\n                             threshold_interaction=args.TI, threshold_distance=args.TD,\n                             threshold_correlation=args.TC, graph=args.Graph, with_lm=True, normalize=True, MergeIndex=args.MergeIndex,\n                             MergeWay=args.MergeWay)\n\nprint('Code version', args.Dataset, args.City, code_version)\n\nprint('Number of training samples', data_loader.train_sequence_len)\n\ndiffusion_matrix = data_loader.diffusion_matrix()\n\nDCRNN_Obj = DCRNN(num_node=data_loader.station_number,\n                  num_diffusion_matrix=diffusion_matrix.shape[0],\n                  num_rnn_units=args.LSTMUnits,\n                  num_rnn_layers=args.LSTMLayers,\n                  max_diffusion_step=args.K,\n                  seq_len=data_loader.closeness_len + data_loader.period_len + data_loader.trend_len,\n                  use_curriculum_learning=False,\n                  input_dim=1,\n                  output_dim=1,\n                  cl_decay_steps=1000,\n                  target_len=1,\n                  lr=args.lr,\n                  epsilon=1e-3,\n                  optimizer_name='Adam',\n                  code_version=code_version,\n                  model_dir=model_dir,\n                  gpu_device=args.Device)\n\n# Build tf-graph\nDCRNN_Obj.build()\n\nprint('Number of trainable parameters', DCRNN_Obj.trainable_vars)\n\n# Training\nDCRNN_Obj.fit(inputs=\n                # np.concatenate((\n                    # data_loader.train_trend.transpose([0, 2, 1, 3]),\n                    # data_loader.train_period.transpose([0, 2, 1, 3]),\n                    data_loader.train_closeness.transpose([0, 2, 1, 3]),\n                # ), axis=1),\n              diffusion_matrix=diffusion_matrix,\n              target=data_loader.train_y.reshape([-1, 1, data_loader.station_number, 1]),\n              batch_size=args.BatchSize,\n              sequence_length=data_loader.train_sequence_len,\n              early_stop_length=args.ESlength,\n              max_epoch=args.Epoch)\n\n# Predict\nprediction = DCRNN_Obj.predict(inputs=\n                    # np.concatenate((\n                    # data_loader.test_trend.transpose([0, 2, 1, 3]),\n                    # data_loader.test_period.transpose([0, 2, 1, 3]),\n                    data_loader.test_closeness.transpose([0, 2, 1, 3]),\n                    # ), axis=1),\n                               diffusion_matrix=diffusion_matrix,\n                               target=data_loader.test_y.reshape([-1, 1, data_loader.station_number, 1]),\n                               sequence_length=data_loader.test_sequence_len,\n                               output_names=['prediction'])\n\n# Evaluate\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.inverse_transform(prediction['prediction']),\n                                 target=data_loader.normalizer.inverse_transform(data_loader.test_y.transpose([0, 2, 1]))))\n\nval_loss = DCRNN_Obj.load_event_scalar('val_loss')\n\nbest_val_loss = min([e[-1] for e in val_loss])\n\nbest_val_loss = data_loader.normalizer.inverse_transform(best_val_loss)\n\nprint('Best val result', best_val_loss)\n\ntime_consumption = [val_loss[e][0] - val_loss[e-1][0] for e in range(1, len(val_loss))]\ntime_consumption = sum([e for e in time_consumption if e < (min(time_consumption) * 10)]) / 3600\nprint('Converged using %.2f hour / %s epochs' % (time_consumption, DCRNN_Obj._global_step))"
  },
  {
    "path": "Experiments/DCRNN/bike_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_dcrnn = ('python DCRNN.py '\n                         '--Dataset Bike '\n                         '--CT 6 '\n                         '--PT 0 '\n                         '--TT 0 '\n                         '--K 1 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 1 '\n                         '--DataRange All '\n                         '--TrainDays 365 '\n                         '--TC 0 '\n                         '--TD 1000 '\n                         '--TI 500 '\n                         '--Epoch 10000 '\n                         '--Train True '\n                         '--lr 5e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 32 '\n                         '--MergeWay sum '\n                         '--Device 0 '\n                         '--CodeVersion V0')\n\nif __name__ == \"__main__\":\n    os.system(shared_params_dcrnn + ' --City NYC --Graph Distance --MergeIndex 1 --DataRange 0.125 --TrainDays 60')\n\n    os.system(shared_params_dcrnn + ' --City DC --Graph Distance --MergeIndex 1 --DataRange 0.125 --TrainDays 60')\n\n    os.system(shared_params_dcrnn + ' --City Chicago --Graph Distance --MergeIndex 1 --DataRange 0.125 --TrainDays 60')\n    \n\n    os.system(shared_params_dcrnn + ' --City NYC --Graph Distance --MergeIndex 3 --DataRange 0.25 --TrainDays 91')\n\n    os.system(shared_params_dcrnn + ' --City DC --Graph Distance --MergeIndex 3 --DataRange 0.25 --TrainDays 91')\n\n    os.system(shared_params_dcrnn + ' --City Chicago --Graph Distance --MergeIndex 3 --DataRange 0.25 --TrainDays 91')\n\n\n    os.system(shared_params_dcrnn + ' --City NYC --Graph Distance --MergeIndex 6 --DataRange 0.5 --TrainDays 183')\n\n    os.system(shared_params_dcrnn + ' --City DC --Graph Distance --MergeIndex 6 --DataRange 0.5 --TrainDays 183')\n\n    os.system(shared_params_dcrnn + ' --City Chicago --Graph Distance --MergeIndex 6 --DataRange 0.5 --TrainDays 183')\n    \n\n    os.system(shared_params_dcrnn + ' --City NYC --Graph Distance --MergeIndex 12')\n\n    os.system(shared_params_dcrnn + ' --City DC --Graph Distance --MergeIndex 12')\n\n    os.system(shared_params_dcrnn + ' --City Chicago --Graph Distance --MergeIndex 12')"
  },
  {
    "path": "Experiments/DCRNN/cs_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_dcrnn = ('python DCRNN.py '\n                         '--Dataset ChargeStation '\n                         '--CT 6 '\n                         '--PT 0 '\n                         '--TT 0 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 1 '\n                         '--DataRange All '\n                         '--TrainDays 365 '\n                         '--TC 0.1 '\n                         '--TD 1000 '\n                         '--TI 500 '\n                         '--Epoch 10000 '\n                         '--Train True '\n                         '--lr 5e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay max '\n                         '--Device 1 ')\n\nif __name__ == \"__main__\":\n    \"\"\"\n    Multiple Graphes\n    \"\"\"\n    os.system(shared_params_dcrnn + ' --City Beijing --K 1 --L 1 '\n                                      ' --Graph Distance --MergeIndex 1')\n\n    os.system(shared_params_dcrnn + ' --City Beijing --K 1 --L 1 '\n                                        ' --Graph Distance --MergeIndex 2')"
  },
  {
    "path": "Experiments/DCRNN/didi_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python DCRNN.py '\n                         '--Dataset DiDi '\n                         '--CT 6 '\n                         '--PT 0 '\n                         '--TT 0 '\n                         '--K 1 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 1 '\n                         '--DataRange All '\n                         '--TrainDays 365 '\n                         '--TC 0.65 '\n                         '--TD 7500 '\n                         '--TI 30 '\n                         '--Epoch 10000 '\n                         '--Train True '\n                         '--lr 1e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay sum '\n                         '--Device 1 '\n                         '--CodeVersion V0')\n\nif __name__ == \"__main__\":\n    os.system(shared_params_st_mgcn + ' --City Chengdu --Graph Distance --MergeIndex 1')\n\n    os.system(shared_params_st_mgcn + ' --City Xian --Graph Distance --MergeIndex 1')\n\n    os.system(shared_params_st_mgcn + ' --City Chengdu --Graph Distance --MergeIndex 3')\n\n    os.system(shared_params_st_mgcn + ' --City Xian --Graph Distance --MergeIndex 3')\n\n    os.system(shared_params_st_mgcn + ' --City Chengdu --Graph Distance --MergeIndex 6')\n\n    os.system(shared_params_st_mgcn + ' --City Xian --Graph Distance --MergeIndex 6')\n\n    os.system(shared_params_st_mgcn + ' --City Chengdu --Graph Distance --MergeIndex 12')\n\n    os.system(shared_params_st_mgcn + ' --City Xian --Graph Distance --MergeIndex 12')"
  },
  {
    "path": "Experiments/DCRNN/metr_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python DCRNN.py '\n                         '--Dataset METR '\n                         '--CT 6 '\n                         '--PT 0 '\n                         '--TT 0 '\n                         '--K 1 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 1 '\n                         '--DataRange All '\n                         '--TrainDays All '\n                         '--TC 0.7 '\n                         '--TD 5500 '\n                         '--TI 30 '\n                         '--Epoch 20000 '\n                         '--test_ratio 0.2 '\n                         '--Train True '\n                         '--lr 1e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay average '\n                         '--Device 1 '\n                         '--CodeVersion V0')\n\nif __name__ == \"__main__\":\n    os.system(shared_params_st_mgcn + ' --City LA --Graph Distance --MergeIndex 1')\n\n    os.system(shared_params_st_mgcn + ' --City LA --Graph Distance --MergeIndex 3')\n\n    os.system(shared_params_st_mgcn + ' --City LA --Graph Distance --MergeIndex 6')\n\n    os.system(shared_params_st_mgcn + ' --City LA --Graph Distance --MergeIndex 12')\n\n  "
  },
  {
    "path": "Experiments/DCRNN/metro_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python DCRNN.py '\n                         '--Dataset Metro '\n                         '--CT 6 '\n                         '--PT 0 '\n                         '--TT 0 '\n                         '--K 1 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 1 '\n                         '--DataRange All '\n                         '--TrainDays 365 '\n                         '--TC 0.7 '\n                         '--TD 5000 '\n                         '--TI 30 '\n                         '--Epoch 20000 '\n                         '--Train True '\n                         '--lr 1e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay sum '\n                         '--Device 1 '\n                         '--CodeVersion V0')\n\nif __name__ == \"__main__\":\n    os.system(shared_params_st_mgcn + ' --City Shanghai --Graph Distance --MergeIndex 1')\n\n    os.system(shared_params_st_mgcn + ' --City Chongqing --Graph Distance --MergeIndex 1')\n\n    os.system(shared_params_st_mgcn + ' --City Shanghai --Graph Distance --MergeIndex 3')\n\n    os.system(shared_params_st_mgcn + ' --City Chongqing --Graph Distance --MergeIndex 3')\n\n    os.system(shared_params_st_mgcn + ' --City Shanghai --Graph Distance --MergeIndex 6')\n\n    os.system(shared_params_st_mgcn + ' --City Chongqing --Graph Distance --MergeIndex 6')\n\n    os.system(shared_params_st_mgcn + ' --City Shanghai --Graph Distance --MergeIndex 12')\n\n    os.system(shared_params_st_mgcn + ' --City Chongqing --Graph Distance --MergeIndex 12')"
  },
  {
    "path": "Experiments/DCRNN/pems_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python DCRNN.py '\n                         '--Dataset PEMS '\n                         '--CT 6 '\n                         '--PT 0 '\n                         '--TT 0 '\n                         '--K 1 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 1 '\n                         '--DataRange All '\n                         '--TrainDays 365 '\n                         '--TC 0.7 '\n                         '--TD 5500 '\n                         '--TI 30 '\n                         '--Epoch 20000 '\n                         '--test_ratio 0.2 '\n                         '--Train True '\n                         '--lr 1e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay average '\n                         '--Device 1 '\n                         '--CodeVersion V0')\n\nif __name__ == \"__main__\":\n    os.system(shared_params_st_mgcn + ' --City BAY --Graph Distance --MergeIndex 1')\n\n    os.system(shared_params_st_mgcn + ' --City BAY --Graph Distance --MergeIndex 3')\n\n    os.system(shared_params_st_mgcn + ' --City BAY --Graph Distance --MergeIndex 6')\n\n    os.system(shared_params_st_mgcn + ' --City BAY --Graph Distance --MergeIndex 12')\n\n  "
  },
  {
    "path": "Experiments/DCRNN/street_didi_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python DCRNN.py '\n                         '--Dataset DiDi '\n                         '--CT 6 '\n                         '--PT 0 '\n                         '--TT 0 '\n                         '--K 1 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 1 '\n                         '--DataRange All '\n                         '--TrainDays 365 '\n                         '--TC 0.65 '\n                         '--TD 7500 '\n                         '--TI 30 '\n                         '--Epoch 10000 '\n                         '--Train True '\n                         '--lr 1e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay sum '\n                         '--Device 1 '\n                         '--CodeVersion V0')\n\nif __name__ == \"__main__\":\n\n    os.system(shared_params_st_mgcn + ' --City Chengdu_Street --Graph Distance --MergeIndex 3')\n\n    os.system(shared_params_st_mgcn + ' --City Xian_Street --Graph Distance --MergeIndex 3')\n\n    os.system(shared_params_st_mgcn + ' --City Chengdu_Street --Graph Distance --MergeIndex 6')\n\n    os.system(shared_params_st_mgcn + ' --City Xian_Street --Graph Distance --MergeIndex 6')\n\n    os.system(shared_params_st_mgcn + ' --City Chengdu_Street --Graph Distance --MergeIndex 12')\n\n    os.system(shared_params_st_mgcn + ' --City Xian_Street --Graph Distance --MergeIndex 12')"
  },
  {
    "path": "Experiments/DeepST/DeepST.py",
    "content": "import nni\n\nfrom UCTB.dataset import GridTrafficLoader\nfrom UCTB.model import DeepST\nfrom UCTB.evaluation import metric\n\nargs = {\n    'dataset': 'DiDi',\n    'city': 'Xian',\n    'num_conv_filters': 64,\n    'kernel_size': 3,\n    'lr': 5e-5,\n    'batch_size': 64,\n    'MergeIndex': 6,\n}\n\ncode_version = 'DeepST_{}_{}_F{}'.format(args['dataset'], args['city'], int(args['MergeIndex'])*5)\n\nnni_params = nni.get_next_parameter()\nnni_sid = nni.get_sequence_id()\nif nni_params:\n    args.update(nni_params)\n    code_version += ('_' + str(nni_sid))\n\n# Config data loader\ndata_loader = GridTrafficLoader(dataset=args['dataset'], city=args['city'],\n                                closeness_len=6, period_len=7, trend_len=4,MergeIndex=args['MergeIndex'])\n\ndeep_st_obj = DeepST(closeness_len=data_loader.closeness_len,\n                     period_len=data_loader.period_len,\n                     trend_len=data_loader.trend_len,\n                     external_dim=data_loader.external_dim,\n                     num_conv_filters=args['num_conv_filters'], kernel_size=args['kernel_size'],\n                     code_version=code_version,\n                     width=data_loader.width, height=data_loader.height, lr=args['lr'])\n\ndeep_st_obj.build()\n\nprint('Trainable variables', deep_st_obj.trainable_vars)\n\n# Training\ndeep_st_obj.fit(closeness_feature=data_loader.train_closeness,\n                period_feature=data_loader.train_period,\n                trend_feature=data_loader.train_trend,\n                target=data_loader.train_y,\n                external_feature=data_loader.train_ef,\n                sequence_length=data_loader.train_sequence_len,\n                batch_size=args['batch_size'],\n                validate_ratio=0.1)\n\n# Predict\nprediction = deep_st_obj.predict(closeness_feature=data_loader.test_closeness,\n                                 period_feature=data_loader.test_period,\n                                 trend_feature=data_loader.test_trend,\n                                 target=data_loader.test_y,\n                                 external_feature=data_loader.test_ef,\n                                 sequence_length=data_loader.test_sequence_len)\n\ntest_rmse = metric.rmse(prediction=data_loader.normalizer.inverse_transform(prediction['prediction']),\n                        target=data_loader.normalizer.inverse_transform(data_loader.test_y))\n\n# Compute metric\nprint('Test result', test_rmse)\n\n# Evaluate\nval_loss = deep_st_obj.load_event_scalar('val_loss')\n\nbest_val_loss = min([e[-1] for e in val_loss])\n# best_val_loss = data_loader.normalizer.inverse_transform(best_val_loss)\n\nprint('Best val result', best_val_loss)\nprint('Test result', test_rmse)\n\nprint('Converged using %.2f hour' % ((val_loss[-1][0] - val_loss[0][0]) / 3600))\nif nni_params:\n    nni.report_final_result({\n        'default': best_val_loss,\n        'test-rmse': test_rmse\n    })"
  },
  {
    "path": "Experiments/DeepST/param_search.yml",
    "content": "authorName: DiChai\r\nexperimentName: search_space\r\ntrialConcurrency: 1\r\nmaxExecDuration: 24h\r\nmaxTrialNum: 50\r\ntrainingServicePlatform: local\r\n# The path to Search Space\r\nsearchSpacePath: search_space.json\r\nuseAnnotation: false\r\ntuner:\r\n  builtinTunerName: GridSearch\r\n# The path and the running command of trial\r\ntrial:\r\n  command: python DeepST.py\r\n  codeDir: .\r\n  gpuNum: 1"
  },
  {
    "path": "Experiments/DeepST/search_space.json",
    "content": "{\r\n    \"num_conv_filters\": {\"_type\":\"choice\",\"_value\":[32, 64, 128]},\r\n\r\n    \"kernel_size\": {\"_type\":\"choice\",\"_value\":[3, 4, 5]},\r\n\r\n    \"lr\": {\"_type\":\"choice\",\"_value\":[0.0001, 0.00002, 0.00004, 0.00008, 0.00001]},\r\n\r\n    \"batch_size\": {\"_type\":\"choice\",\"_value\":[32, 64, 128, 256]}\r\n}"
  },
  {
    "path": "Experiments/GBRT/GBRT.py",
    "content": "import numpy as np\nimport argparse\nfrom sklearn.ensemble import GradientBoostingRegressor\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess import SplitData\nimport nni\nimport os\n\nparams = {\n    'CT': 12,\n    'PT': 14,\n    'TT': 1,\n    'max_depth': 7,\n    'num_boost_round': 182\n}\n\n\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\n# data source\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\nparser.add_argument('--dataset', default='Metro', type=str)\nparser.add_argument('--city', default='Chongqing',type=str)\nparser.add_argument('--MergeIndex', default=3)\nparser.add_argument('--DataRange', default=\"all\")\nparser.add_argument('--TrainDays', default=\"all\")\nparser.add_argument('--MergeWay', default=\"sum\")\nparser.add_argument('--test_ratio', default=0.1, type=float)\n\n#use params and args to show its difference\nargs = vars(parser.parse_args())\n\nparams.update(nni.get_next_parameter())\n\n\ndata_loader = NodeTrafficLoader(dataset=args[\"dataset\"], city=args['city'], closeness_len=int(params['CT']), period_len=int(params['PT']), trend_len=int(params['TT']),\n                                data_range=args['DataRange'], train_data_length=args['TrainDays'],\n                                test_ratio=args['test_ratio'],\n                                with_lm=False, normalize=False, MergeIndex=args['MergeIndex'],\n                                MergeWay=args['MergeWay'])\n\n\ntrain_closeness, val_closeness = SplitData.split_data(\n    data_loader.train_closeness, [0.9, 0.1])\ntrain_period, val_period = SplitData.split_data(\n    data_loader.train_period, [0.9, 0.1])\ntrain_trend, val_trend = SplitData.split_data(\n    data_loader.train_trend, [0.9, 0.1])\n\ntrain_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\n\nprediction_test = []\nprediction_val = []\n\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = GradientBoostingRegressor(n_estimators=int(params['num_boost_round']), max_depth=int(params['max_depth']))\n\n    X_Train = []\n    X_Val = []\n    X_Test = []\n    if int(params['CT']) > 0:\n        X_Train.append(train_closeness[:, i, :, 0])\n        X_Val.append(val_closeness[:, i, :, 0])\n        X_Test.append(data_loader.test_closeness[:, i, :, 0])\n    if int(params['PT']) > 0:\n        X_Train.append(train_period[:, i, :, 0])\n        X_Val.append(val_period[:, i, :, 0])\n        X_Test.append(data_loader.test_period[:, i, :, 0])\n    if int(params['TT']) > 0:\n        X_Train.append(train_trend[:, i, :, 0])\n        X_Val.append(val_trend[:, i, :, 0])\n        X_Test.append(data_loader.test_trend[:, i, :, 0])\n\n    X_Train = np.concatenate(X_Train, axis=-1)\n    X_Val = np.concatenate(X_Val, axis=-1)\n    X_Test = np.concatenate(X_Test, axis=-1)\n\n    model.fit(X_Train, train_y[:, i, 0])\n\n    p_val = model.predict(X_Val)\n    p_test = model.predict(X_Test)\n\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\n    prediction_val.append(p_val.reshape([-1, 1, 1]))\n\nprediction_test = np.concatenate(prediction_test, axis=-2)\nprediction_val = np.concatenate(prediction_val, axis=-2)\n\nprint('Val RMSE', metric.rmse(prediction_val, val_y))\nprint('Test RMSE', metric.rmse(prediction_test, data_loader.test_y))\n\nnni.report_final_result({'default': metric.rmse(prediction_val, val_y),\n                         'test-rmse': metric.rmse(prediction_test, data_loader.test_y)})\n"
  },
  {
    "path": "Experiments/GBRT/gbrt_config.yml",
    "content": "authorName: lychen\nexperimentName: gbrt_parameter_search\ntrialConcurrency: 1\nmaxExecDuration: 72h\nmaxTrialNum: 200\ntrainingServicePlatform: local\n# The path to Search Space\nsearchSpacePath: gbrt_search_space.json\nuseAnnotation: false\ntuner:\n  builtinTunerName: TPE\n# The path and the running command of trial\ntrial:\n  # python GBRT.py --dataset Metro --city Chongqing --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays all\n  # python GBRT.py --dataset DiDi --city Xian --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays all\n  # python GBRT.py --dataset Bike --city NYC --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays 365\n  # python GBRT.py --dataset ChargeStation --city Beijing --MergeIndex 1 --MergeWay max --DataRange all --TrainDays all\n  # python GBRT.py --dataset Taxi --city BJ --MergeIndex 2 --MergeWay sum --DataRange all --TrainDays all\n  # python GBRT.py --dataset METR --city LA --MergeIndex 3 --MergeWay average --DataRange all --TrainDays all --test_ratio 0.2\n  # python GBRT.py --dataset PEMS --city BAY --MergeIndex 3 --MergeWay average --DataRange all --TrainDays all --test_ratio 0.2\n  # python GBRT.py --dataset PEMS --city BAY --MergeIndex 12 --MergeWay average --DataRange all --TrainDays all --test_ratio 0.2\n  command:  python GBRT.py --dataset DiDi --city Chengdu_Street --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays all\n  codeDir: .\n  gpuNum: 0 "
  },
  {
    "path": "Experiments/GBRT/gbrt_search_space.json",
    "content": "{\n\n    \"CT\": {\"_type\": \"randint\", \"_value\": [0,13]},\n    \"PT\": {\"_type\": \"randint\", \"_value\": [0,15]},\n    \"TT\": {\"_type\": \"randint\", \"_value\": [0,5]},\n\n    \"max_depth\": {\"_type\":\"randint\",\"_value\":[1, 11]},\n    \"num_boost_round\": {\"_type\":\"randint\",\"_value\":[10, 201]}\n}"
  },
  {
    "path": "Experiments/GMAN/GMAN.py",
    "content": "import time\nimport argparse\nimport os\n\nfrom UCTB.evaluation import metric\nfrom UCTB.model.GMAN import Graph\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\nfrom UCTB.utils.utils_GMAN import *\n\n#args config\nparser = argparse.ArgumentParser()\n# data loader parameters\nparser.add_argument(\"--dataset\", default='Bike', type=str)\nparser.add_argument(\"--city\", default='NYC', type=str)\nparser.add_argument(\"--closeness_len\", default=12, type=int)\nparser.add_argument(\"--period_len\", default=0, type=int)\nparser.add_argument(\"--trend_len\", default=0, type=int)\nparser.add_argument(\"--data_range\", default=\"all\", type=str)\nparser.add_argument(\"--train_data_length\", default=\"all\", type=str)\nparser.add_argument(\"--test_ratio\", default=0.1, type=float)\nparser.add_argument(\"--MergeIndex\", default=1, type=int)\nparser.add_argument(\"--MergeWay\", default=\"sum\", type=str)\nparser.add_argument(\"--threshold_correlation\", default=0.7, type=float)\n\nparser.add_argument('--Q', type=int, default=1,\n                    help='prediction steps')\nparser.add_argument('--L', type=int, default=1,\n                    help='number of STAtt Blocks')\nparser.add_argument('--K', type=int, default=8,\n                    help='number of attention heads')\nparser.add_argument('--d', type=int, default=8,\n                    help='dims of each head attention outputs')\nparser.add_argument('--train_ratio', type=float, default=0.7,\n                    help='training set [default : 0.7]')\nparser.add_argument('--val_ratio', type=float, default=0.1,\n                    help='validation set [default : 0.1]')\nparser.add_argument('--batch_size', type=int, default=8,\n                    help='batch size')\nparser.add_argument('--max_epoch', type=int, default=500,\n                    help='epoch to run')\nparser.add_argument('--patience', type=int, default=40,\n                    help='patience for early stop')\nparser.add_argument('--learning_rate', type=float, default=0.001,\n                    help='initial learning rate')\nparser.add_argument('--decay_epoch', type=int, default=5,\n                    help='decay epoch')\n\n# spatial embedding parameters\nparser.add_argument('--spatial_is_directed', type=bool, default=False)\nparser.add_argument('--spatial_p', type=int, default=2)\nparser.add_argument('--spatial_q', type=int, default=1)\nparser.add_argument('--spatial_num_walks', type=int, default=100)\nparser.add_argument('--spatial_walk_length', type=int, default=80)\nparser.add_argument('--spatial_dimensions', type=int, default=32)\nparser.add_argument('--spatial_epochs', type=int, default=1000)\n\n\nargs = parser.parse_args()\n\n#config data_loader\ndata_loader = NodeTrafficLoader(dataset=args.dataset, city=args.city,\n                                data_range=args.data_range, train_data_length=args.train_data_length,\n                                test_ratio=float(args.test_ratio),\n                                closeness_len=args.closeness_len,\n                                period_len=args.period_len,\n                                trend_len=args.trend_len,\n                                normalize=False, remove=False,\n                                MergeIndex=args.MergeIndex,\n                                MergeWay=args.MergeWay)\n\nargs.P = args.closeness_len + args.period_len + args.trend_len\n\ngraph_obj = GraphGenerator(graph='correlation', data_loader=data_loader,\n                           threshold_distance=args.threshold_correlation)\n\n# Global variable\nadj_file = os.path.abspath(\"./Graph_File/{}_{}_adj.txt\".format(args.dataset, args.city))\nSE_file = os.path.abspath(\"./Graph_File/{}_{}_SE.txt\".format(args.dataset, args.city))\nargs.SE_file = SE_file\n\nif not os.path.exists(SE_file):\n    # Generate Graph embedding\n    graph_to_adj_files(graph_obj.AM[0], adj_file)\n\n    nx_G = read_graph(adj_file)\n    G = Graph(nx_G, args.spatial_is_directed, args.spatial_p, args.spatial_q)\n    G.preprocess_transition_probs()\n\n    walks = G.simulate_walks(args.spatial_num_walks, args.spatial_walk_length)\n    learn_embeddings(walks, args.spatial_dimensions, SE_file, args.spatial_epochs)\n\n\nmodel_name = os.path.abspath(\"model_dir/{}_{}_{}/\".format(args.dataset, args.city, args.MergeIndex))\nif not os.path.exists(model_name):\n    os.makedirs(model_name)\nargs.model_file = model_name\nprint(\"model_name:\", args.model_file)\n\nlog_file = os.path.abspath(\"log/{}_{}_{}.txt\".format(args.dataset, args.city, args.MergeIndex))\nif not os.path.exists(os.path.dirname(log_file)):\n    os.makedirs(os.path.dirname(log_file))\nargs.log_file = log_file\nprint(\"log_file:\", args.log_file)\n\n\nstart = time.time()\nlog = open(args.log_file, 'w')\nlog_string(log, str(args)[10: -1])\n\n# load data\nlog_string(log, 'loading data...')\n\n(trainX, trainTE, trainY, valX, valTE, valY, testX, testTE, testY,\n SE,time_fitness) = load_data(args, data_loader)\n\n\nlog_string(log, 'trainX: %s\\ttrainY: %s' % (trainX.shape, trainY.shape))\nlog_string(log, 'valX:   %s\\t\\tvalY:   %s' % (valX.shape, valY.shape))\nlog_string(log, 'testX:  %s\\t\\ttestY:  %s' % (testX.shape, testY.shape))\nlog_string(log, 'data loaded!')\n\n# Train and Test\nX, TE, label, is_training, saver, sess, train_op, loss, pred = build_model(\n    log, time_fitness, trainX, args,SE)\n\ntrain_prediction, val_prediction = Train(\n    log, args, trainX, trainY, trainTE, valX, valTE, valY, X, TE, label, is_training, saver, sess, train_op, loss, pred)\n\ntest_prediction = Test(log, args, testX, testTE, X,\n                       TE, is_training, sess, pred)\ntest_prediction = data_loader.normalizer.inverse_transform(test_prediction)\ny_true = data_loader.normalizer.inverse_transform(data_loader.test_y)\ntest_rmse = metric.rmse(prediction=test_prediction.squeeze(),\n                        target=y_true.squeeze())\n\nprint(\"Test RMSE:\", test_rmse)\n"
  },
  {
    "path": "Experiments/GMAN/Runner.py",
    "content": "import os\n\nimport os\n\n#############################################\n# BenchMark Bike\n#############################################\n# ########### NYC ########### \n# # # os.system(\"python GMAN.py --dataset Bike --city NYC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset Bike --city NYC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# # os.system(\"python GMAN.py --dataset Bike --city NYC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n\n# # # # # ########### Chicago ###########\n# # # # # # os.system(\"python GMAN.py --dataset Bike --city Chicago --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset Bike --city Chicago --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# # os.system(\"python GMAN.py --dataset Bike --city Chicago --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n\n# # # # # ########### DC ###########\n# # # # # # os.system(\"python GMAN.py --dataset Bike --city DC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset Bike --city DC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# # os.system(\"python GMAN.py --dataset Bike --city DC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n\n\n# # # # # # ###############################################\n# # # # # # # BenchMark DiDi\n# # # # # # ###############################################\n# # # # # # ############# Xian #############\n# # # # # # # os.system(\"python GMAN.py --dataset DiDi --city Xian --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset DiDi --city Xian --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# # # # os.system(\"python GMAN.py --dataset DiDi --city Xian --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# # # # # # ############# Chengdu #############\n# # # # # # # os.system(\"python GMAN.py --dataset DiDi --city Chengdu --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset DiDi --city Chengdu --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset DiDi --city Chengdu --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n\n\n# # # # # # ###############################################\n# # # # # # # BenchMark Metro\n# # # # # # ###############################################\n# # # # # # ############# Chongqing #############\n# # # # # # # os.system(\"python GMAN.py --dataset Metro --city Chongqing --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset Metro --city Chongqing --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# # # os.system(\"python GMAN.py --dataset Metro --city Chongqing --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n\n# # # # # # ############# Shanghai #############\n# # # # # # # os.system(\"python GMAN.py --dataset Metro --city Shanghai --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset Metro --city Shanghai --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset Metro --city Shanghai --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n\n\n# # # # # ###############################################\n# # # # # # BenchMark ChargeStation\n# # # # # ###############################################\n\n# os.system(\"python GMAN.py --dataset ChargeStation --city Beijing --MergeIndex 1 --MergeWay max --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# # # os.system(\"python GMAN.py --dataset ChargeStation --city Beijing --MergeIndex 2 --MergeWay max --closeness_len 12 --period_len 0 --trend_len 0\")\n\n\n\n# # # # # # ###############################################\n# # # # # # # BenchMark METR-LA\n# # # # # # ###############################################\n\n# # # # # # # os.system(\"python GMAN.py --dataset METR --city LA --MergeIndex 3 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset METR --city LA --MergeIndex 6 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0\")\n\nos.system(\"python GMAN.py --dataset METR --city LA --MergeIndex 12 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0\")\n\n\n# # # # # # ###############################################\n# # # # # # # BenchMark PEMS-BAY\n# # # # # # ###############################################\n# # # # # # # os.system(\"python GMAN.py --dataset PEMS --city BAY --MergeIndex 3 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset PEMS --city BAY --MergeIndex 6 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset PEMS --city BAY --MergeIndex 12 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0\")\n\n\n# # # ###############################################\n# # # # BenchMark DiDi_Street\n# # # ###############################################\n# # # ############# Xian_Street #############\n# os.system(\"python GMAN.py --dataset DiDi --city Xian_Street --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset DiDi --city Xian_Street --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset DiDi --city Xian_Street --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# ############ Chengdu_Street #############\n# os.system(\"python GMAN.py --dataset DiDi --city Chengdu_Street --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset DiDi --city Chengdu_Street --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n\n# os.system(\"python GMAN.py --dataset DiDi --city Chengdu_Street --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0\")\n"
  },
  {
    "path": "Experiments/GraphWaveNet/GraphWaveNet.py",
    "content": "import torch\nimport argparse\nimport time\nimport os\n\nfrom UCTB.utils.utils_GraphWaveNet import *\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\nfrom UCTB.dataset import NodeTrafficLoader, data_loader\nfrom UCTB.evaluation import metric\n\n\nparser = argparse.ArgumentParser()\nparser.add_argument('--device', type=str, default='cuda:0', help='')\nparser.add_argument('--data', type=str, default='data/METR-LA', help='data path')\nparser.add_argument('--adjdata', type=str, default='data/sensor_graph/adj_mx.pkl', help='adj data path')\nparser.add_argument('--adjtype', type=str, default='doubletransition', help='adj type')\nparser.add_argument('--gcn_bool', action='store_true', help='whether to add graph convolution layer')\nparser.add_argument('--aptonly', action='store_true', help='whether only adaptive adj')\nparser.add_argument('--addaptadj', action='store_true', help='whether add adaptive adj')\nparser.add_argument('--randomadj', action='store_true', help='whether random initialize adaptive adj')\nparser.add_argument('--seq_length', type=int, default=1, help='')\nparser.add_argument('--nhid', type=int, default=32, help='')\nparser.add_argument('--in_dim', type=int, default=1, help='inputs dimension')\nparser.add_argument('--num_nodes', type=int, default=207, help='number of nodes')\nparser.add_argument('--batch_size', type=int, default=32, help='batch size')\nparser.add_argument('--learning_rate', type=float, default=0.001, help='learning rate')\nparser.add_argument('--dropout', type=float, default=0.3, help='dropout rate')\nparser.add_argument('--weight_decay', type=float, default=0.0001, help='weight decay rate')\nparser.add_argument('--epochs', type=int, default=100, help='')\nparser.add_argument('--print_every', type=int, default=50, help='')\n# parser.add_argument('--seed',type=int,default=99,help='random seed')\nparser.add_argument('--save', type=str, default='./garage/metr', help='save path')\nparser.add_argument('--expid', type=int, default=1, help='experiment id')\n# data parameters\nparser.add_argument(\"--dataset\", default='DiDi', type=str, help=\"configuration file path\")\nparser.add_argument(\"--city\", default='Xian', type=str)\nparser.add_argument(\"--closeness_len\", default=6, type=int)\nparser.add_argument(\"--period_len\", default=7, type=int)\nparser.add_argument(\"--trend_len\", default=4, type=int)\nparser.add_argument(\"--data_range\", default=\"all\", type=str)\nparser.add_argument(\"--train_data_length\", default=\"all\", type=str)\nparser.add_argument(\"--test_ratio\", default=0.1, type=float)\nparser.add_argument(\"--MergeIndex\", default=1, type=int)\nparser.add_argument(\"--MergeWay\", default=\"sum\", type=str)\n\nargs = parser.parse_args()\n\n# loading data\nuctb_data_loader = NodeTrafficLoader(dataset=args.dataset, city=args.city,\n                                     data_range=args.data_range, train_data_length=args.train_data_length,\n                                     test_ratio=float(args.test_ratio),\n                                     closeness_len=args.closeness_len,\n                                     period_len=args.period_len,\n                                     trend_len=args.trend_len,\n                                     normalize=False,\n                                     MergeIndex=args.MergeIndex,\n                                     MergeWay=args.MergeWay)\n\nargs.num_nodes = uctb_data_loader.station_number\nargs.in_dim = uctb_data_loader.closeness_len + uctb_data_loader.period_len + uctb_data_loader.trend_len\nargs.seq_length = 1\nargs.save = os.path.abspath('./experiment/{}_{}_{}'.format(args.dataset, args.city, args.MergeIndex))\nif not os.path.exists(args.save):\n    os.makedirs(args.save)\n\n# Build Graph\ngraph_obj = GraphGenerator(graph='distance', data_loader=uctb_data_loader)\n\n\ndevice = torch.device(args.device)\ndata_dict = load_dataset(uctb_data_loader, args.batch_size, args.batch_size, args.batch_size)\n\n\n    \nsupports = [torch.tensor(graph_obj.AM[i]).to(device) for i in range(len(graph_obj.AM))]\n\nprint(args)\nt1 = time.time()\nif args.randomadj:\n    adjinit = None\nelse:\n    adjinit = supports[0]\nif args.aptonly:\n    supports = None\nengine = trainer(args.in_dim, args.seq_length, args.num_nodes, args.nhid, args.dropout,\n                 args.learning_rate, args.weight_decay, device, supports, args.gcn_bool, args.addaptadj,\n                 adjinit)\n\nepoch_id, loss_id = Training(args, data_dict, device, engine)\n\nprint(\"epoch_id:\", epoch_id, \"loss_id:\", loss_id)\n\ntest_prediction = Test(args, data_dict, device, engine,  epoch_id, loss_id)\ntest_prediction = uctb_data_loader.normalizer.inverse_transform(test_prediction)\ny_true = uctb_data_loader.normalizer.inverse_transform(uctb_data_loader.test_y)\nrmse_result = metric.rmse(prediction=test_prediction.squeeze(),\n                        target=y_true.squeeze())\nprint(\"Test RMSE:\", rmse_result)\n\nt2 = time.time()\nprint(\"Total time spent: {:.4f}\".format(t2 - t1))\n\n\n"
  },
  {
    "path": "Experiments/GraphWaveNet/Runner.py",
    "content": "import os\n\n#############################################\n# BenchMark Bike\n#############################################\n########### NYC ###########\n# os.system(\"python GraphWaveNet.py --dataset Bike --city NYC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset Bike --city NYC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset Bike --city NYC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n\n# ########### Chicago ###########\nos.system(\"python GraphWaveNet.py --dataset Bike --city Chicago --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# # os.system(\"python GraphWaveNet.py --dataset Bike --city Chicago --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset Bike --city Chicago --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n\n# ########### DC ###########\n# # os.system(\"python GraphWaveNet.py --dataset Bike --city DC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# # os.system(\"python GraphWaveNet.py --dataset Bike --city DC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset Bike --city DC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n\n\n# ###############################################\n# # BenchMark DiDi\n# ###############################################\n# ############# Xian #############\n# # os.system(\"python GraphWaveNet.py --dataset DiDi --city Xian --MergeIndex 3 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# # os.system(\"python GraphWaveNet.py --dataset DiDi --city Xian --MergeIndex 6 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset DiDi --city Xian --MergeIndex 12 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# ############# Chengdu #############\n# # os.system(\"python GraphWaveNet.py --dataset DiDi --city Chengdu --MergeIndex 3 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# # os.system(\"python GraphWaveNet.py --dataset DiDi --city Chengdu --MergeIndex 6 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset DiDi --city Chengdu --MergeIndex 12 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n\n\n# ###############################################\n# # BenchMark Metro\n# ###############################################\n# ############# Chongqing #############\n# # os.system(\"python GraphWaveNet.py --dataset Metro --city Chongqing --MergeIndex 3 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# # os.system(\"python GraphWaveNet.py --dataset Metro --city Chongqing --MergeIndex 6 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset Metro --city Chongqing --MergeIndex 12 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n\n# ############# Shanghai #############\n# # os.system(\"python GraphWaveNet.py --dataset Metro --city Shanghai --MergeIndex 3 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# # os.system(\"python GraphWaveNet.py --dataset Metro --city Shanghai --MergeIndex 6 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset Metro --city Shanghai --MergeIndex 12 --MergeWay sum --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n\n\n# ###############################################\n# # BenchMark ChargeStation\n# ###############################################\n\n# os.system(\"python GraphWaveNet.py --dataset ChargeStation --city Beijing --MergeIndex 1 --MergeWay max --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset ChargeStation --city Beijing --MergeIndex 2 --MergeWay max --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n\n# ###############################################\n# # BenchMark METR-LA\n# ###############################################\n\n# # os.system(\"python GraphWaveNet.py --dataset METR --city LA --MergeIndex 3 --MergeWay average --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# # os.system(\"python GraphWaveNet.py --dataset METR --city LA --MergeIndex 6 --MergeWay average --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset METR --city LA --MergeIndex 12 --MergeWay average --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n\n# ###############################################\n# # BenchMark PEMS-BAY\n# ###############################################\n# # os.system(\"python GraphWaveNet.py --dataset PEMS --city BAY --MergeIndex 3 --MergeWay average --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# # os.system(\"python GraphWaveNet.py --dataset PEMS --city BAY --MergeIndex 6 --MergeWay average --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n\n# os.system(\"python GraphWaveNet.py --dataset PEMS --city BAY --MergeIndex 12 --MergeWay average --gcn_bool --adjtype doubletransition --addaptadj  --randomadj\")\n"
  },
  {
    "path": "Experiments/HM/HM.py",
    "content": "from UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import HM\nimport argparse\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess import SplitData\nimport nni\nimport os\n\n\nparams = {\n    'CT': 0,\n    'PT': 0,\n    'TT': 4,\n}\n\nparams.update(nni.get_next_parameter())\n\n\n# acquire data source path\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\nparser.add_argument('--dataset', default='Metro', type=str)\nparser.add_argument('--city', default=\"Shanghai\", type=str)\nparser.add_argument('--MergeIndex', default=1)\nparser.add_argument('--DataRange', default=\"all\")\nparser.add_argument('--TrainDays', default=\"all\")\nparser.add_argument('--MergeWay', default=\"sum\")\nparser.add_argument('--test_ratio', default=0.1, type=float)\n\n# note that the args is different from param\nargs = vars(parser.parse_args())\n\n\ndata_loader = NodeTrafficLoader(dataset=args[\"dataset\"], city=args['city'], closeness_len=int(params['CT']), period_len=int(params['PT']), trend_len=int(params['TT']),\n                                data_range=args['DataRange'], train_data_length=args['TrainDays'],\n                                test_ratio=args['test_ratio'],\n                                with_lm=False, normalize=False, MergeIndex=args['MergeIndex'],\n                                MergeWay=args['MergeWay'])\n\ntrain_closeness, val_closeness = SplitData.split_data(\n    data_loader.train_closeness, [0.9, 0.1])\ntrain_period, val_period = SplitData.split_data(\n    data_loader.train_period, [0.9, 0.1])\ntrain_trend, val_trend = SplitData.split_data(\n    data_loader.train_trend, [0.9, 0.1])\n\n\ntrain_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\n\n\nhm_obj = HM(c=data_loader.closeness_len,\n            p=data_loader.period_len, t=data_loader.trend_len)\n\n\ntest_prediction = hm_obj.predict(closeness_feature=data_loader.test_closeness,\n                                 period_feature=data_loader.test_period,\n                                 trend_feature=data_loader.test_trend)\n\nval_prediction = hm_obj.predict(closeness_feature=val_closeness,\n                                period_feature=val_period,\n                                trend_feature=val_trend)\n\n\nprint('Test RMSE', metric.rmse(test_prediction, data_loader.test_y))\nprint('Val RMSE', metric.rmse(val_prediction, val_y))\n\n\nnni.report_final_result({'default': metric.rmse(val_prediction, val_y),\n                         'test-rmse': metric.rmse(test_prediction, data_loader.test_y)})\n"
  },
  {
    "path": "Experiments/HM/hm_closeness_search_space.json",
    "content": "{\n    \"CT\": {\"_type\": \"choice\", \"_value\": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]},\n    \"PT\": {\"_type\": \"choice\", \"_value\": [0]},\n    \"TT\": {\"_type\": \"choice\", \"_value\": [0]}\n}"
  },
  {
    "path": "Experiments/HM/hm_config.yml",
    "content": "authorName: lychen\nexperimentName: hm_parameter_search\ntrialConcurrency: 2\nmaxExecDuration: 24h\nmaxTrialNum: 24\ntrainingServicePlatform: local\n# The path to Search Space\nsearchSpacePath: hm_closeness_search_space.json\nuseAnnotation: false\ntuner:\n  builtinTunerName: TPE\n# The path and the running command of trial\ntrial:\n  # python HM.py --dataset Metro --city Chongqing --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays all\n  # python HM.py --dataset DiDi --city Xian --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays all\n  # python HM.py --dataset Bike --city NYC --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays 365\n  # python HM.py --dataset ChargeStation --city Beijing --MergeIndex 1 --MergeWay max --DataRange all --TrainDays all\n  # python HM.py --dataset Taxi --city BJ --MergeIndex 2 --MergeWay sum --DataRange all --TrainDays all\n  # python HM.py --dataset METR --city LA --MergeIndex 3 --MergeWay average --DataRange all --TrainDays all --test_ratio 0.2\n  # python HM.py --dataset PEMS --city BAY --MergeIndex 3 --MergeWay average --DataRange all --TrainDays all --test_ratio 0.2\n  # python HM.py --dataset PEMS --city BAY --MergeIndex 1 --MergeWay average --DataRange all --TrainDays all --test_ratio 0.2\n  # python HM.py --dataset DiDi --city Chengdu_Street --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays all\n  command: python HM.py --dataset DiDi --city Xian_Street --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays all\n\n  #0.25,train_data_length:91,graph:Distance,MergeIndex:3\n  codeDir: .\n  gpuNum: 0"
  },
  {
    "path": "Experiments/HM/hm_search_space.json",
    "content": "{\n    \"CT\": {\"_type\": \"choice\", \"_value\": [0,1,2,3,4,5,6]},\n    \"PT\": {\"_type\": \"choice\", \"_value\": [0,1,2,3,4,5,6,7]},\n    \"TT\": {\"_type\": \"choice\", \"_value\": [0,1,2,3,4]}\n}"
  },
  {
    "path": "Experiments/HMM/HMM.py",
    "content": "import nni\nimport argparse\n\nfrom UCTB.model import HMM\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess import SplitData\n\n\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\n# data source\nparser.add_argument('--Dataset', default='Bike')\nparser.add_argument('--City', default='DC')\n# network parameter\nparser.add_argument('--CT', default='6', type=int)\nparser.add_argument('--PT', default='7', type=int)\nparser.add_argument('--TT', default='4', type=int)\n\nparser.add_argument('--DataRange', default='All')\nparser.add_argument('--TrainDays', default='365')\n\nparser.add_argument('--num_components', type=int, default=8)\nparser.add_argument('--n_iter', type=int, default=365)\n\n\nargs = vars(parser.parse_args())\n\nnni_params = nni.get_next_parameter()\nnni_sid = nni.get_sequence_id()\nif nni_params:\n    args.update(nni_params)\n    args['CodeVersion'] += str(nni_sid)\n\n\ndata_loader = NodeTrafficLoader(dataset=args['Dataset'], city=args['City'],\n                                closeness_len=args['CT'], period_len=args['PT'], trend_len=args['TT'],\n                                with_lm=False, with_tpe=False, normalize=False)\n\nmodel = HMM(num_components=args['num_components'], n_iter=args['n_iter'])\n\ntrain_closeness, val_closeness = SplitData.split_data(data_loader.train_closeness, [0.9, 0.1])\ntrain_period, val_period = SplitData.split_data(data_loader.train_period, [0.9, 0.1])\ntrain_trend, val_trend = SplitData.split_data(data_loader.train_trend, [0.9, 0.1])\n\ntrain_label, val_label = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\n\nmodel.fit(X=(train_closeness, train_period, train_trend), y=train_label)\n\nval_results = model.predict(X=(val_closeness, val_period, val_trend))\ntest_results = model.predict(X=(data_loader.test_closeness, data_loader.test_period, data_loader.test_trend))\n\nval_rmse = metric.rmse(val_results, val_label)\ntest_rmse = metric.rmse(test_results, data_loader.test_y)\n\nprint(args['Dataset'], args['City'], 'val_rmse', val_rmse)\nprint(args['Dataset'], args['City'], 'test_rmse', test_rmse)"
  },
  {
    "path": "Experiments/HMM/trials.py",
    "content": "import os\n\nfrom UCTB.utils import multiple_process\n\n\ndef task_func(share_queue, locker, data, parameters):\n\n    print('Child process %s with pid %s' % (parameters[0], os.getpid()))\n\n    for task in data:\n        print('Child process', parameters[0], 'running', task)\n        exec_str = 'python HMM.py --Dataset %s --City %s ' % (task[0], task[1])\n        if task[2] != '':\n            exec_str += task[2]\n        os.system(exec_str)\n\n    locker.acquire()\n    share_queue.put(None)\n    locker.release()\n\n\nif __name__ == '__main__':\n\n    task_list = [\n        ['Bike', 'NYC', ''],\n        ['Bike', 'Chicago', ''],\n        ['Bike', 'DC', ''],\n        ['Metro', 'Chongqing', ''],\n        ['Metro', 'Shanghai', ''],\n        ['DiDi', 'Chengdu', ''],\n        ['DiDi', 'Xian', ''],\n        ['ChargeStation', 'Beijing', '']\n    ]\n\n    n_jobs = 2\n\n    multiple_process(distribute_list=task_list,\n                     partition_func=lambda data, i, n_job: [data[e] for e in range(len(data)) if e % n_job == i],\n                     task_func=task_func, n_jobs=n_jobs,\n                     reduce_func=lambda x, y: None, parameters=[])\n\n"
  },
  {
    "path": "Experiments/MTGNN/MTGNN.py",
    "content": "import argparse\nfrom UCTB.dataset import NodeTrafficLoader\nimport os\nfrom UCTB.utils.utils_MTGNN import load_dataset\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\nfrom UCTB.dataset import NodeTrafficLoader\n# from UCTB.evaluation import metric\nfrom UCTB.utils.utils_MTGNN import *\nfrom UCTB.model.MTGNN import gtnet\nimport pdb\nimport time\ndef str_to_bool(value):\n    if isinstance(value, bool):\n        return value\n    if value.lower() in {'false', 'f', '0', 'no', 'n'}:\n        return False\n    elif value.lower() in {'true', 't', '1', 'yes', 'y'}:\n        return True\n    raise ValueError(f'{value} is not a valid boolean value')\n\nparser = argparse.ArgumentParser(description='PyTorch Time series forecasting')\n\nparser.add_argument('--device',type=str,default='cuda:0',help='')\nparser.add_argument('--data',type=str,default='data/METR-LA',help='data path')\n\nparser.add_argument('--adj_data', type=str,default='data/sensor_graph/adj_mx.pkl',help='adj data path')\nparser.add_argument('--gcn_true', type=str_to_bool, default=True, help='whether to add graph convolution layer')\nparser.add_argument('--buildA_true', type=str_to_bool, default=True,help='whether to construct adaptive adjacency matrix')\nparser.add_argument('--load_static_feature', type=str_to_bool, default=False,help='whether to load static feature')\nparser.add_argument('--cl', type=str_to_bool, default=True,help='whether to do curriculum learning')\n\nparser.add_argument('--gcn_depth',type=int,default=2,help='graph convolution depth')\nparser.add_argument('--num_nodes',type=int,default=207,help='number of nodes/variables')\nparser.add_argument('--dropout',type=float,default=0.3,help='dropout rate')\nparser.add_argument('--subgraph_size',type=int,default=20,help='k')\nparser.add_argument('--node_dim',type=int,default=40,help='dim of nodes')\nparser.add_argument('--dilation_exponential',type=int,default=1,help='dilation exponential')\n\nparser.add_argument('--conv_channels',type=int,default=32,help='convolution channels')\nparser.add_argument('--residual_channels',type=int,default=32,help='residual channels')\nparser.add_argument('--skip_channels',type=int,default=64,help='skip channels')\nparser.add_argument('--end_channels',type=int,default=128,help='end channels')\n\n\nparser.add_argument('--in_dim',type=int,default=1,help='inputs dimension')\nparser.add_argument('--seq_in_len',type=int,default=12,help='input sequence length')\nparser.add_argument('--seq_out_len',type=int,default=12,help='output sequence length')\n\nparser.add_argument('--layers',type=int,default=3,help='number of layers')\nparser.add_argument('--batch_size',type=int,default=32,help='batch size')\nparser.add_argument('--learning_rate',type=float,default=0.001,help='learning rate')\nparser.add_argument('--weight_decay',type=float,default=0.0001,help='weight decay rate')\nparser.add_argument('--clip',type=int,default=5,help='clip')\nparser.add_argument('--step_size1',type=int,default=2500,help='step_size')\nparser.add_argument('--step_size2',type=int,default=100,help='step_size')\n\n\nparser.add_argument('--epochs',type=int,default=100,help='')\nparser.add_argument('--print_every',type=int,default=50,help='')\nparser.add_argument('--seed',type=int,default=101,help='random seed')\nparser.add_argument('--save',type=str,default='./save/',help='save path')\nparser.add_argument('--expid',type=int,default=1,help='experiment id')\n\nparser.add_argument('--propalpha',type=float,default=0.05,help='prop alpha')\nparser.add_argument('--tanhalpha',type=float,default=3,help='adj alpha')\n\nparser.add_argument('--num_split',type=int,default=1,help='number of splits for graphs')\n\nparser.add_argument('--runs',type=int,default=10,help='number of runs')\n\n# data parameters\nparser.add_argument(\"--dataset\", default='METR', type=str, help=\"configuration file path\")\nparser.add_argument(\"--city\", default='LA', type=str)\nparser.add_argument(\"--closeness_len\", default=6, type=int)\nparser.add_argument(\"--period_len\", default=7, type=int)\nparser.add_argument(\"--trend_len\", default=4, type=int)\nparser.add_argument(\"--data_range\", default=\"all\", type=str)\nparser.add_argument(\"--train_data_length\", default=\"all\", type=str)\nparser.add_argument(\"--test_ratio\", default=0.2, type=float)\nparser.add_argument(\"--MergeIndex\", default=6, type=int)\nparser.add_argument(\"--MergeWay\", default=\"average\", type=str)\n\nargs = parser.parse_args()\n\n# loading data\nuctb_data_loader = NodeTrafficLoader(dataset=args.dataset, city=args.city,data_dir='data',\n                                     data_range=args.data_range, train_data_length=args.train_data_length,\n                                     test_ratio=float(args.test_ratio),\n                                     closeness_len=args.closeness_len,\n                                     period_len=args.period_len,\n                                     trend_len=args.trend_len,\n                                     normalize=True,\n                                     MergeIndex=args.MergeIndex,\n                                     MergeWay=args.MergeWay)\n# pdb.set_trace()\nargs.num_nodes = uctb_data_loader.station_number\nargs.seq_in_len = uctb_data_loader.closeness_len + uctb_data_loader.period_len + uctb_data_loader.trend_len\nargs.seq_out_len = 1\nargs.save = os.path.abspath('./experiment/MTGNN_{}_{}_{}/'.format(args.dataset, args.city, args.MergeIndex))\nif not os.path.exists(args.save):\n    os.makedirs(args.save)\n    \n# Build Graph\n# graph_obj = GraphGenerator(graph='distance', data_loader=uctb_data_loader)\n\n\ndevice = torch.device(args.device)\ndata_dict = load_dataset(uctb_data_loader, args.batch_size, args.batch_size, args.batch_size)\n# 需要改下\n# predefined_A = graph_obj.AM[0]\n# predefined_A = torch.tensor(predefined_A)-torch.eye(args.num_nodes)\n# predefined_A = predefined_A.to(device)\n\nmodel = gtnet(args.gcn_true, args.buildA_true, args.gcn_depth, args.num_nodes,\n                  device, dropout=args.dropout, subgraph_size=args.subgraph_size,\n                  node_dim=args.node_dim, dilation_exponential=args.dilation_exponential,\n                  conv_channels=args.conv_channels, residual_channels=args.residual_channels,\n                  skip_channels=args.skip_channels, end_channels= args.end_channels,\n                  seq_length=args.seq_in_len, in_dim=args.in_dim, out_dim=args.seq_out_len,\n                  layers=args.layers, propalpha=args.propalpha, tanhalpha=args.tanhalpha, layer_norm_affline=False)\nmodel = model.to(device)\nprint(args)\nprint('The recpetive field size is', model.receptive_field)\nnParams = sum([p.nelement() for p in model.parameters()])\nprint('Number of model parameters is', nParams)\nengine = Trainer(model, args.learning_rate, args.weight_decay, args.clip, args.step_size1, args.seq_out_len, device, args.cl)\nprint(\"start training...\",flush=True)\nhis_loss =[]\nval_time = []\ntrain_time = []\nminl = 1e5\n# pdb.set_trace()\nfor i in range(1,args.epochs+1):\n    train_loss = []\n    train_mape = []\n    train_rmse = []\n    t1 = time.time()\n    data_dict['train_loader'].shuffle()\n    for iter, (x, y) in enumerate(data_dict['train_loader'].get_iterator()):\n        trainx = torch.Tensor(x).to(device)\n        trainx= trainx.transpose(1, 3)\n        trainy = torch.Tensor(y).to(device)\n        trainy = trainy.transpose(1, 3)\n        # pdb.set_trace()\n        if iter%args.step_size2==0:\n            perm = np.random.permutation(range(args.num_nodes))\n        num_sub = int(args.num_nodes/args.num_split)\n        for j in range(args.num_split):\n            if j != args.num_split-1:\n                id = perm[j * num_sub:(j + 1) * num_sub]\n            else:\n                id = perm[j * num_sub:]\n            id = torch.tensor(id).to(device)\n            tx = trainx[:, :, id, :]\n            ty = trainy[:, :, id, :]\n            metrics = engine.train(tx, ty[:,0,:,:],id)\n            train_loss.append(metrics[0])\n            train_mape.append(metrics[1])\n            train_rmse.append(metrics[2])\n        if iter % args.print_every == 0 :\n            log = 'Iter: {:03d}, Train Loss: {:.4f}, Train MAPE: {:.4f}, Train RMSE: {:.4f}'\n            print(log.format(iter, train_loss[-1], train_mape[-1], train_rmse[-1]),flush=True)\n    t2 = time.time()\n    train_time.append(t2-t1)\n    #validation\n    valid_loss = []\n    valid_mape = []\n    valid_rmse = []\n    s1 = time.time()\n    for iter, (x, y) in enumerate(data_dict['val_loader'].get_iterator()):\n        testx = torch.Tensor(x).to(device)\n        testx = testx.transpose(1, 3)\n        testy = torch.Tensor(y).to(device)\n        testy = testy.transpose(1, 3)\n        metrics = engine.eval(testx, testy[:,0,:,:])\n        valid_loss.append(metrics[0])\n        valid_mape.append(metrics[1])\n        valid_rmse.append(metrics[2])\n    s2 = time.time()\n    log = 'Epoch: {:03d}, Inference Time: {:.4f} secs'\n    print(log.format(i,(s2-s1)))\n    val_time.append(s2-s1)\n    mtrain_loss = np.mean(train_loss)\n    mtrain_mape = np.mean(train_mape)\n    mtrain_rmse = np.mean(train_rmse)\n    mvalid_loss = np.mean(valid_loss)\n    mvalid_mape = np.mean(valid_mape)\n    mvalid_rmse = np.mean(valid_rmse)\n    his_loss.append(mvalid_loss)\n    log = 'Epoch: {:03d}, Train Loss: {:.4f}, Train MAPE: {:.4f}, Train RMSE: {:.4f}, Valid Loss: {:.4f}, Valid MAPE: {:.4f}, Valid RMSE: {:.4f}, Training Time: {:.4f}/epoch'\n    print(log.format(i, mtrain_loss, mtrain_mape, mtrain_rmse, mvalid_loss, mvalid_mape, mvalid_rmse, (t2 - t1)),flush=True)\n    if mvalid_loss<minl:\n        torch.save(engine.model.state_dict(), args.save + \"/exp\" + str(args.expid) + '_' + str(i) +'_' + \".pth\")\n        minl = mvalid_loss\nprint(\"Average Training Time: {:.4f} secs/epoch\".format(np.mean(train_time)))\nprint(\"Average Inference Time: {:.4f} secs\".format(np.mean(val_time)))\nbestid = np.argmin(his_loss)\nengine.model.load_state_dict(torch.load(args.save + \"/exp\" + str(args.expid) + '_' + str(bestid+1) +'_' + \".pth\"))\nprint(\"Training finished\")\nprint(\"The valid loss on best model is\", str(round(his_loss[bestid],4)))\n# #valid data\n# outputs = []\n# realy = torch.Tensor(data_dict['y_val']).to(device)\n# realy = realy.transpose(1,3)[:,0,:,:]\n# for iter, (x, y) in enumerate(data_dict['val_loader'].get_iterator()):\n#     testx = torch.Tensor(x).to(device)\n#     testx = testx.transpose(1,3)\n#     with torch.no_grad():\n#         preds = engine.model(testx)\n#         preds = preds.transpose(1,3)\n#     outputs.append(preds.squeeze())\n# yhat = torch.cat(outputs,dim=0)\n# yhat = yhat[:realy.size(0),...]\n# pred = yhat\n# vmae, vmape, vrmse = metric(pred,realy)\n#test data\noutputs = []\nrealy = torch.Tensor(data_dict['y_test']).to(device)\nrealy = realy.transpose(1, 3)[:, 0, :, :]\nfor iter, (x, y) in enumerate(data_dict['test_loader'].get_iterator()):\n    testx = torch.Tensor(x).to(device)\n    testx = testx.transpose(1, 3)\n    with torch.no_grad():\n        preds = engine.model(testx)\n        preds = preds.transpose(1, 3)\n    outputs.append(preds.squeeze())\ny_truth = uctb_data_loader.normalizer.inverse_transform(uctb_data_loader.test_y)\nyhat = torch.cat(outputs, dim=0).cpu().numpy()\nyhat = yhat[:realy.size(0), ...]\nyhat = uctb_data_loader.normalizer.inverse_transform(yhat)\nyhat = yhat[...,np.newaxis]\nfrom UCTB.evaluation.metric import rmse,mape,mae\nprint('Test RMSE',rmse(yhat,y_truth,1))\nprint('Test MAE',mae(yhat,y_truth,1))\nprint('Test MAPE',mape(yhat,y_truth,1))\nnp.save('MTGNN_Bike_Chicago_test_pred',yhat)\nnp.save('MTGNN_Bike_Chicago_test_truth',y_truth)\n"
  },
  {
    "path": "Experiments/MTGNN/Runner.py",
    "content": ""
  },
  {
    "path": "Experiments/MultiStepPredict/Code/DirRec_ARIMA.py",
    "content": "import time\nimport numpy as np\nimport pandas as pd\nfrom sklearn.metrics import mean_absolute_error as MAE\n\nfrom UCTB.model import ARIMA\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\n\n# params\ndataset_name = \"Bike_NYC\"\nmodel_name = \"DirRec_ARIMA\"\noutput_path = \"../Outputs/\"+model_name+\"-\"+dataset_name\n\nn_pred = 12\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=24, period_len=0, trend_len=0, target_length=n_pred, with_lm=False, normalize=False)\n\nstart = time.time()\n\ntest_prediction_collector = []\nfor i in range(data_loader.station_number):\n    try:\n        model_obj = ARIMA(time_sequence=data_loader.train_closeness[:, i, -1, 0],\n                          order=[6, 0, 1], seasonal_order=[0, 0, 0, 0])\n        test_prediction = model_obj.predict(time_sequences=data_loader.test_closeness[:, i, :, 0],\n                                            forecast_step=n_pred)\n    except Exception as e:\n        print('Converge failed with error', e)\n        print('Using last as prediction')\n        test_prediction = data_loader.test_closeness[:, i, -1:, :]\n    test_prediction_collector.append(test_prediction)\n    print('Station', i, 'finished')\n\npredict_list = np.array(test_prediction_collector)\npredict_list = predict_list.transpose([1, 0, 2])\n\nprint('Total time cost is %.3f' % float(time.time()-start))\nprediction = predict_list\nprediction = np.where(prediction>0, prediction, 0)\ntarget = data_loader.test_y\nevaluation_result = pd.DataFrame(columns=[\"MAE\", \"RMSE\", \"MAPE\"], index=range(1, n_pred+1))\nfor i in range(n_pred):\n    # reshape\n    cur_prediction = prediction[:,:,i]\n    cur_target = target[:,:,i]\n    # result\n    mae = MAE(cur_prediction, cur_target)\n    rmse = metric.rmse(cur_prediction, cur_target)\n    mape = metric.mape(cur_prediction, cur_target, threshold=0.1)\n    # save\n    evaluation_result.loc[i+1, \"MAE\"] = mae\n    evaluation_result.loc[i+1, \"RMSE\"] = rmse\n    evaluation_result.loc[i+1, \"MAPE\"] = mape\n    # print\n    print(\"Step %02d, MAE: %.4f, RMSE: %.4f, MAPE:%.4f\" % (i+1, mae, rmse, mape))\n\n# save\nnp.save(output_path + '-prediction.npy', prediction)\nnp.save(output_path + '-target.npy', target)\nevaluation_result.to_csv(output_path + '-evaluation.csv', float_format=\"%.4f\")"
  },
  {
    "path": "Experiments/MultiStepPredict/Code/DirRec_DCRNN.py",
    "content": "import time\nimport numpy as np\nimport pandas as pd\nfrom sklearn.metrics import mean_absolute_error as MAE\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import DCRNN\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n\nclass my_data_loader(NodeTrafficLoader):\n\n    def __init__(self, **kwargs):\n\n        super(my_data_loader, self).__init__(**kwargs) \n        \n        # generate LM\n        graph_obj = GraphGenerator(graph=kwargs['graph'], data_loader=self)\n        self.AM = graph_obj.AM\n        self.LM = graph_obj.LM\n\n    def diffusion_matrix(self, filter_type='random_walk'):\n        def calculate_random_walk_matrix(adjacent_mx):\n            d = np.array(adjacent_mx.sum(1))\n            d_inv = np.power(d, -1).flatten()\n            d_inv[np.isinf(d_inv)] = 0.\n            d_mat_inv = np.diag(d_inv)\n            random_walk_mx = d_mat_inv.dot(adjacent_mx)\n            return random_walk_mx\n        assert len(self.AM) == 1\n\n        diffusion_matrix = []\n        if filter_type == \"random_walk\":\n            diffusion_matrix.append(calculate_random_walk_matrix(self.AM[0]).T)\n        elif filter_type == \"dual_random_walk\":\n            diffusion_matrix.append(calculate_random_walk_matrix(self.AM[0]).T)\n            diffusion_matrix.append(calculate_random_walk_matrix(self.AM[0].T).T)\n        return np.array(diffusion_matrix, dtype=np.float32)\n\n\n# params\ndataset_name = \"Bike_NYC\"\nmodel_name = \"DirRec_DCRNN\"\noutput_path = \"../Outputs/\"+model_name+\"-\"+dataset_name\nmodel_dir = \"../Outputs/model_dir\"\ncode_version = model_name+\"-\"+dataset_name\nbatch_size = 64\nn_pred = 12\ngpu_device = '0'\n\ndata_loader = my_data_loader(dataset='Bike', city='NYC', train_data_length='365',\n                             closeness_len=6, period_len=7, trend_len=4, target_length=n_pred, graph='Correlation', normalize=True)\n\nstart = time.time()\n\ndiffusion_matrix = data_loader.diffusion_matrix()\n\n# define n_pred model to train\nmodel_list = []\ntemp_predict = []\ntemp_trainX = np.concatenate((data_loader.train_trend.transpose([0, 2, 1, 3]), data_loader.train_period.transpose([0, 2, 1, 3]), data_loader.train_closeness.transpose([0, 2, 1, 3])), axis=1)\nfor i in range(n_pred):\n    temp_input_len = data_loader.closeness_len + data_loader.period_len + data_loader.trend_len + i\n    temp_code_version = code_version + \"-Step_\"+ str(i+1)\n    if i != 0:\n        temp_trainX = np.concatenate((temp_trainX,temp_predict), axis=1)\n    temp_model = DCRNN(num_node=data_loader.station_number,\n        num_diffusion_matrix=diffusion_matrix.shape[0],\n        num_rnn_units=64,\n        num_rnn_layers=1,\n        max_diffusion_step=2,\n        seq_len=temp_input_len,\n        use_curriculum_learning=False,\n        input_dim=1,\n        output_dim=1,\n        cl_decay_steps=1000,\n        target_len=1,\n        lr=1e-4,\n        epsilon=1e-3,\n        optimizer_name='Adam',\n        code_version=temp_code_version,\n        model_dir=model_dir,\n        gpu_device=gpu_device)\n    # tf-graph\n    temp_model.build()\n    # training\n    temp_model.fit(inputs=temp_trainX,\n        diffusion_matrix=diffusion_matrix,\n        target=data_loader.train_y[:, :, i].reshape([-1, 1, data_loader.station_number, 1]),\n        batch_size=batch_size,\n        sequence_length=data_loader.train_sequence_len,\n        early_stop_length=100,\n        max_epoch=1000)\n    # save\n    model_list.append(temp_model)\n    # prediction\n    temp_predict = temp_model.predict(\n        inputs=temp_trainX,\n        diffusion_matrix=diffusion_matrix,\n        target=data_loader.train_y[:, :, i].reshape([-1, 1, data_loader.station_number, 1]),\n        sequence_length=data_loader.train_sequence_len,\n        output_names=['prediction']\n    )\n    # predict shape is [train_sequence_len, output_dim, station_number]\n    temp_predict = temp_predict['prediction']\n    temp_predict = temp_predict.reshape((temp_predict.shape[0], temp_predict.shape[1], temp_predict.shape[2], 1))\n\n# use n_pred model to predict n_pred step\npredict_list = []\ntemp_predict = []\ntemp_testX = np.concatenate((data_loader.test_trend.transpose([0, 2, 1, 3]), data_loader.test_period.transpose([0, 2, 1, 3]), data_loader.test_closeness.transpose([0, 2, 1, 3])), axis=1)\nfor i in range(n_pred):\n    temp_model = model_list[i]\n    if i != 0:\n        temp_testX = np.concatenate((temp_testX, temp_predict), axis=1)\n    temp_predict = temp_model.predict(\n        inputs=temp_testX,\n        diffusion_matrix=diffusion_matrix,\n        target=data_loader.test_y[:, :, i].reshape([-1, 1, data_loader.station_number, 1]),\n        sequence_length=data_loader.test_sequence_len,\n        output_names=['prediction']\n    )\n    temp_predict = temp_predict['prediction']\n    predict_list.append(temp_predict)\n    temp_predict = temp_predict.reshape((temp_predict.shape[0], temp_predict.shape[1], temp_predict.shape[2], 1))\n\nprint('Total time cost is %.3f' % float(time.time()-start))\n\n# Evaluation\npredict_list = np.array(predict_list)\npredict_list = predict_list.transpose([1, 3, 0, 2])\npredict_list = predict_list.reshape((predict_list.shape[0], predict_list.shape[1], predict_list.shape[2]))\nprediction = data_loader.normalizer.min_max_denormal(predict_list)\nprediction = np.where(prediction>0, prediction, 0)\ntarget = data_loader.normalizer.min_max_denormal(data_loader.test_y)\n\nevaluation_result = pd.DataFrame(columns=[\"MAE\", \"RMSE\", \"MAPE\"], index=range(1, n_pred+1))\nfor i in range(n_pred):\n    # reshape\n    cur_prediction = prediction[:,:,i]\n    cur_target = target[:,:,i]\n    # result\n    mae = MAE(cur_prediction, cur_target)\n    rmse = metric.rmse(cur_prediction, cur_target)\n    mape = metric.mape(cur_prediction, cur_target, threshold=0.1)\n    # save\n    evaluation_result.loc[i+1, \"MAE\"] = mae\n    evaluation_result.loc[i+1, \"RMSE\"] = rmse\n    evaluation_result.loc[i+1, \"MAPE\"] = mape\n    # print\n    print(\"Step %02d, MAE: %.4f, RMSE: %.4f, MAPE:%.4f\" % (i+1, mae, rmse, mape))\n\n# save\nnp.save(output_path + '-prediction.npy', prediction)\nnp.save(output_path + '-target.npy', target)\nevaluation_result.to_csv(output_path + '-evaluation.csv', float_format=\"%.4f\")"
  },
  {
    "path": "Experiments/MultiStepPredict/Code/DirRec_STMeta.py",
    "content": "import time\nimport numpy as np\nimport pandas as pd\nfrom sklearn.metrics import mean_absolute_error as MAE\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n\n\n# params\ndataset_name = \"Bike_NYC\"\nmodel_name = \"DirRec_STMeta\"\noutput_path = \"../Outputs/\"+model_name+\"-\"+dataset_name\nmodel_dir = \"../Outputs/model_dir\"\ncode_version = model_name+\"-\"+dataset_name\nn_pred = 12\ngpu_device = '1'\n\n# Config data loader\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=6, period_len=7, trend_len=4, target_length=n_pred, normalize=True)\n\nstart = time.time()\n\n# Build Graph\ngraph_obj = GraphGenerator(graph='Correlation', data_loader=data_loader)\n\n# define n_pred model to train\nmodel_list = []\ntemp_predict = []\ntemp_closeness_feature = data_loader.train_closeness\nfor i in range(n_pred):\n    temp_closeness_len = data_loader.closeness_len + i\n    temp_code_version = code_version + \"-Step_\"+ str(i+1)\n    if i != 0:\n        temp_closeness_feature = np.concatenate((temp_closeness_feature, temp_predict), axis=2)\n    temp_model = STMeta(closeness_len=temp_closeness_len,\n                    period_len=data_loader.period_len,\n                    trend_len=data_loader.trend_len,\n                    num_node=data_loader.station_number,\n                    num_graph=graph_obj.LM.shape[0],\n                    external_dim=data_loader.external_dim,\n                    code_version=temp_code_version,\n                    model_dir=model_dir,\n                    gpu_device=gpu_device)\n    # Build tf-graph\n    temp_model.build()\n    # Training\n    temp_model.fit(closeness_feature=temp_closeness_feature,\n                period_feature=data_loader.train_period,\n                trend_feature=data_loader.train_trend,\n                laplace_matrix=graph_obj.LM,\n                target=data_loader.train_y[:,:,i].reshape((-1, data_loader.station_number, 1)),\n                external_feature=data_loader.train_ef,\n                sequence_length=data_loader.train_sequence_len,\n                auto_load_model = False)\n    # save\n    model_list.append(temp_model)\n    # prediction\n    temp_predict = temp_model.predict(closeness_feature=temp_closeness_feature,\n                period_feature=data_loader.train_period,\n                trend_feature=data_loader.train_trend,\n                laplace_matrix=graph_obj.LM,\n                target=data_loader.train_y[:,:,i].reshape((-1, data_loader.station_number, 1)),\n                external_feature=data_loader.train_ef,\n                output_names=['prediction'],\n                sequence_length=data_loader.train_sequence_len)\n    # predict shape is [sequence_len, station_num, 1]\n    temp_predict = temp_predict['prediction']\n    temp_predict = temp_predict.reshape((temp_predict.shape[0], temp_predict.shape[1], 1, 1))\n\n# use n_pred model to predict n_pred step\npredict_list = []\ntemp_predict = []\ntemp_closeness_feature = data_loader.test_closeness\nfor i in range(n_pred):\n    temp_model = model_list[i]\n    if i != 0:\n        temp_closeness_feature = np.concatenate((temp_closeness_feature, temp_predict), axis=2)\n    # prediction\n    temp_predict = temp_model.predict(closeness_feature=temp_closeness_feature,\n                period_feature=data_loader.test_period,\n                trend_feature=data_loader.test_trend,\n                laplace_matrix=graph_obj.LM,\n                target=data_loader.test_y[:,:,i].reshape((-1, data_loader.station_number, 1)),\n                external_feature=data_loader.test_ef,\n                output_names=['prediction'],\n                sequence_length=data_loader.test_sequence_len)\n    temp_predict = temp_predict['prediction']\n    # predict shape is [sequence_len, station_num, 1]\n    predict_list.append(temp_predict)\n    temp_predict = temp_predict.reshape((temp_predict.shape[0], temp_predict.shape[1], 1, 1))\n\nprint('Total time cost is %.3f' % float(time.time()-start))\n\n# Evaluation\npredict_list = np.concatenate(predict_list, axis=2)\nprediction = data_loader.normalizer.min_max_denormal(predict_list)\nprediction = np.where(prediction>0, prediction, 0)\ntarget = data_loader.normalizer.min_max_denormal(data_loader.test_y)\n\nevaluation_result = pd.DataFrame(columns=[\"MAE\", \"RMSE\", \"MAPE\"], index=range(1, n_pred+1))\nfor i in range(n_pred):\n    # reshape\n    cur_prediction = prediction[:,:,i]\n    cur_target = target[:,:,i]\n    # result\n    mae = MAE(cur_prediction, cur_target)\n    rmse = metric.rmse(cur_prediction, cur_target)\n    mape = metric.mape(cur_prediction, cur_target, threshold=0.1)\n    # save\n    evaluation_result.loc[i+1, \"MAE\"] = mae\n    evaluation_result.loc[i+1, \"RMSE\"] = rmse\n    evaluation_result.loc[i+1, \"MAPE\"] = mape\n    # print\n    print(\"Step %02d, MAE: %.4f, RMSE: %.4f, MAPE:%.4f\" % (i+1, mae, rmse, mape))\n\n# save\nnp.save(output_path + '-prediction.npy', prediction)\nnp.save(output_path + '-target.npy', target)\nevaluation_result.to_csv(output_path + '-evaluation.csv', float_format=\"%.4f\")\n    \n"
  },
  {
    "path": "Experiments/MultiStepPredict/Code/DirRec_XGBoost.py",
    "content": "import time\nimport numpy as np\nimport pandas as pd\nfrom sklearn.metrics import mean_absolute_error as MAE\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import XGBoost\nfrom UCTB.evaluation import metric\n\n\n# params\ndataset_name = \"Bike_NYC\"\nmodel_name = \"DirRec_XGBoost\"\noutput_path = \"../Outputs/\"+model_name+\"-\"+dataset_name\nmodel_dir = \"../Outputs/model_dir\"\ncode_version = model_name+\"-\"+dataset_name\nbatch_size = 64\nn_pred = 12\ngpu_device = '0'\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=6, period_len=7, trend_len=4, target_length=n_pred, with_lm=False, normalize=False)\n\nstart = time.time()\n\n# define (station_number * n_pred) model to train\nmodel_list = []\ntemp_predict = []\nnode_predict = []\ntemp_trainX = np.concatenate((data_loader.train_trend, data_loader.train_period, data_loader.train_closeness), axis = 2)\nfor i in range(n_pred):\n    model_list.append([])\n    if i != 0:\n        temp_trainX = np.concatenate((temp_trainX,temp_predict), axis=2)\n    temp_predict = []\n    for j in range(data_loader.station_number):\n        print('Step %d, Station %d' % (i, j))\n        # define\n        temp_model = XGBoost(n_estimators=100, max_depth=3, objective='reg:squarederror')\n        # train\n        temp_model.fit(temp_trainX[:, j, :, 0], data_loader.train_y[:, j, i])\n        # save\n        model_list[i].append(temp_model)\n        # predict\n        node_predict = temp_model.predict(temp_trainX[:, j, :, 0])\n        temp_predict.append(node_predict.reshape((-1, 1, 1)))\n    # temp_predict shape is [sequence_len, station_number, 1]\n    temp_predict = np.concatenate(temp_predict, axis=1)\n    temp_predict = temp_predict.reshape((temp_predict.shape[0], temp_predict.shape[1], 1, 1))\n\n\n# 使用H个模型预测得到未来H步\npredict_list = []\ntemp_predict = []\nnode_predict = []\ntemp_testX = np.concatenate((data_loader.test_trend, data_loader.test_period, data_loader.test_closeness), axis = 2)\nfor i in range(n_pred):\n    if i != 0:\n        temp_testX = np.concatenate((temp_testX,temp_predict), axis=2)\n    temp_predict = []\n    for j in range(data_loader.station_number):\n        temp_model = model_list[i][j]\n        node_predict = temp_model.predict(temp_testX[:, j, :, 0])\n        temp_predict.append(node_predict.reshape((-1, 1, 1)))\n    # temp_predict shape is [sequence_len, station_number, 1]\n    temp_predict = np.concatenate(temp_predict, axis=1)\n    predict_list.append(temp_predict)\n    temp_predict = temp_predict.reshape((temp_predict.shape[0], temp_predict.shape[1], 1, 1))\n\nprint('Total time cost is %.3f' % float(time.time()-start))\n# Evaluation\npredict_list = np.concatenate(predict_list, axis=2)\nprediction = np.where(predict_list>0, predict_list, 0)\ntarget = data_loader.test_y\nevaluation_result = pd.DataFrame(columns=[\"MAE\", \"RMSE\", \"MAPE\"], index=range(1, n_pred+1))\nfor i in range(n_pred):\n    # reshape\n    cur_prediction = prediction[:,:,i]\n    cur_target = target[:,:,i]\n    # result\n    mae = MAE(cur_prediction, cur_target)\n    rmse = metric.rmse(cur_prediction, cur_target)\n    mape = metric.mape(cur_prediction, cur_target, threshold=0.1)\n    # save\n    evaluation_result.loc[i+1, \"MAE\"] = mae\n    evaluation_result.loc[i+1, \"RMSE\"] = rmse\n    evaluation_result.loc[i+1, \"MAPE\"] = mape\n    # print\n    print(\"Step %02d, MAE: %.4f, RMSE: %.4f, MAPE:%.4f\" % (i+1, mae, rmse, mape))\n\n# save\nnp.save(output_path + '-prediction.npy', prediction)\nnp.save(output_path + '-target.npy', target)\nevaluation_result.to_csv(output_path + '-evaluation.csv', float_format=\"%.4f\")"
  },
  {
    "path": "Experiments/MultiStepPredict/Code/viz.py",
    "content": "import pandas as pd\nimport matplotlib.pyplot as plt\nimport numpy as np\n\ndef readMetric(metric_name, eva_dir, horizon_num):\n    \"\"\"\n    Read evaluation matrices from multiple files, each row corresponds to a time step, and each column corresponds to an evaluation matrix (MAE\\RMSE\\MAPE) result\n    output: shape is (eva_num, model_num, horizon_num)\n    \"\"\"\n    eva_num = len(metric_name)\n    model_num = len(eva_dir)\n    result = np.zeros((eva_num, horizon_num, model_num))\n    for m in range(model_num):\n        cur_eva = pd.read_csv(eva_dir[m], header=0, index_col=0).values\n        for e in range(eva_num):\n            for h in range(horizon_num):\n                result[e, h, m] = cur_eva[h, e]\n    return result\n\n\ndef plot(eva_metric, metric_name, model_name, dataset_name, horizon_num):\n    \"\"\"\n    plot\n    \"\"\"\n    eva_num = len(metric_name)\n    model_num = len(model_name)\n    x = list(range(1, horizon_num+1))\n    color_list = ['cornflowerblue', 'mediumorchid', 'forestgreen', 'cyan', 'darkorange', 'chocolate', 'red']\n    marker_list = ['^', 'o', 'v', '<', '>', '*', 's']\n\n    # plot\n    for e in range(eva_num):\n        fig = plt.figure(0, dpi=300, figsize=(8, 5))\n        plt.title(\"multi step \"+metric_name[e])\n        plt.xlabel('Horizon')\n        plt.ylabel(metric_name[e] + ' on '+ dataset_name)\n        for m in range(model_num):\n            plt.plot(x, eva_metric[e, :, m], marker=marker_list[-m], color=color_list[-m], markersize=8)\n        plt.legend(model_name)\n        plt.savefig('../Figure/'+ dataset_name + '_' + metric_name[e]+'.png')\n        plt.close(0)\n\n\nif __name__==\"__main__\":\n    # params\n    horizon_num = 12\n    dataset_name = \"Bike_NYC\"\n    metric_name = [\"MAE\", \"RMSE\", \"MAPE\"]\n    # model_name = [\"DirRec_ARIMA\",\"DirRec_XGBoost\",\"DirRec_DCRNN\",\"DirRec_STMeta\"]\n    model_name = [\"DirRec_ARIMA\",\"DirRec_XGBoost\",\"DirRec_DCRNN_mini\",\"DirRec_STMeta_mini\"]\n    eva_dir = list(map(lambda x: \"../Outputs/\" + x + \"-\" + dataset_name + \"-evaluation.csv\", model_name))\n    # read and plot\n    eva_metric = readMetric(metric_name, eva_dir, horizon_num)\n    plot(eva_metric, metric_name, model_name, dataset_name, horizon_num)\n"
  },
  {
    "path": "Experiments/MultiStepPredict/README.md",
    "content": "## Method\n\nThe implementation of multi-step prediction refers to the following survey.\n\n> An N H, Anh D T. Comparison of strategies for multi-step-ahead prediction of time series using neural network[C]//2015 International Conference on Advanced Computing and Applications (ACOMP). IEEE, 2015: 142-149.\n\nSpecifically, the paper shows that the multi-step prediction based on the `DirRec` strategy achieves the best results on multiple datasets and time steps. The core strategy of `DirRec` is to use a different model to predict each time step in the future, which augments the input of the next prediction by adding the prediction value of the previous step. The formula description is as follows:\n$$\n\\hat{y}_{N+h}=\n\\begin{cases}\n\\hat{f}_{h}(y_{N},...,y_{N-d+1})\\ \\ &if \\ \\ h=1 \\\\\n\\hat{f}_{h}(\\hat{y}_{N+h-1},...,\\hat{y}_{N+1},y_{N},...,y_{N-d+1}) & if \\ \\ h\\in \\{2,...,H\\}\n\\end{cases}\n$$\nThe architecture is shown below:\n\n<img src=\"Figure/DirRec_Strategy.png\" alt=\"DirRec_Strategy\" style=\"zoom:70%;\" />\n\n## Changes to the original code\n\n### UCTB/Dataset/data_loader\n\nThe original `target_length` defaults to 1, and the `target_length` parameter does not take effect during the parameter transfer process, but a constant `1` is always passed as a parameter, so the original lines 106~109 are modified as follows:\n\n```python\n        # init move sample obj\n        self.st_move_sample = ST_MoveSample(closeness_len=closeness_len,\n                                            period_len=period_len,\n                                            trend_len=trend_len, target_length=target_length, daily_slots=self.daily_slots)\n```\n\n### UCTB/model/ARIMA\n\nThe modification of ARIMA is concentrated in the prediction part, the shape returned by the original prediction method in multi-step prediction is `[math.ceil(len(time_sequences) / forecast_step), forecast_step]`. In fact, the output shape we need is `[len(time_sequences) , forecast_step]`, so the `predict` function in the `ARIMA` class under `UCTB.model` has been modified as follows:\n\n```python\n    def predict(self, time_sequences, forecast_step=1):\n        '''\n        Argues:\n            time_sequences: The input time_series features.\n            forecast_step: The number of predicted future steps. Default: 1\n        \n        :return: Prediction results with shape of (len(time_sequence)/forecast_step,forecast_step=,1).\n        :type: np.ndarray\n        '''\n        result = []\n        \"\"\" origin predict method, output shape is [math.ceil(len(time_sequences) / forecast_step), forecast_step]\n        for i in range(0, len(time_sequences), forecast_step):\n            fs = forecast_step if ((i + forecast_step) < len(time_sequences)) else (len(time_sequences) - i)\n            model = sm.tsa.SARIMAX(time_sequences[i], order=self.order, seasonal_order=self.seasonal_order)\n            model_res = model.filter(self.model_res.params)\n            p = model_res.forecast(fs).reshape([-1, 1])\n            result.append(p)\n        \"\"\"\n        # new predict method, output shape is [len(time_sequences), forecast_step]\n        for i in range(len(time_sequences)):\n            model = sm.tsa.SARIMAX(time_sequences[i], order=self.order, seasonal_order=self.seasonal_order)\n            model_res = model.filter(self.model_res.params)\n            p = model_res.forecast(forecast_step)\n            p = p.reshape([-1, forecast_step])\n            result.append(p)\n        if forecast_step != 1:\n            result = np.concatenate(result, axis=0)\n        return np.array(result, dtype=np.float32)\n```\n\n### UCTB/model/XGBoost\n\nThe original parameter name contains spaces, and an error will be reported at runtime. The specific error message is as follows:\n\n> xgboost.core.XGBoostError: [12:34:15] ../src/learner.cc:553: Invalid parameter \"verbosity \" contains whitespace.\n\nSpecifically, modify the original lines 23 to 28 as follows:\n\n```python\n        self.param = {\n            'max_depth': max_depth,\n            'verbosity': verbosity,\n            'objective': objective,\n            'eval_metric': eval_metric\n        }\n```\n\n## Run\n\nSet the parameters. Different models will have different input parameters. See the code for details. The common thing is to set the prediction step, and the current experiment is uniformly set to 12.\n\n```python\nn_pred = 12\ngpu_device = '0'\n```\n\nSwitch directory\n\n```shell\ncd Experiments/MultiStepPredict/Code\n```\n\nRun\n\n```Shell\nnohup python -u DirRec_STMeta.py >DirRec_STMeta.log 2>&1 &\n```\n\nAfter the execution, it will output `DirRec_STMeta.log` in the current folder, and output `DirRec_STMeta-Bike_NYC-evaluation.csv`, `DirRec_STMeta-Bike_NYC-prediction.npy`, `DirRec_STMeta-Bike_NYC-target.npy` in the `Outputs` directory.\n\nIn addition, a visualization method is provided to easily read the evaluation results of different models, and visualize them together for comparison. Execute the following commands, and the visualization results `Bike_NYC_MAE.png`, `Bike_NYC_RMSE.png`,  `Bike_NYC_MAPE.png`will be generated in the `Figure` directory.\n\n```shell\npython viz.py\n```"
  },
  {
    "path": "Experiments/ParameterSearch/ARIMA.py",
    "content": "import numpy as np\r\n\r\nfrom UCTB.model import ARIMA\r\nfrom UCTB.dataset import NodeTrafficLoader\r\nfrom UCTB.evaluation import metric\r\n\r\ndata_loader = NodeTrafficLoader(dataset='ChargeStation', city='Beijing')\r\n\r\nprediction = []\r\n\r\nfor i in range(data_loader.station_number):\r\n\r\n    print('*************************************************************')\r\n    print('Station', i)\r\n\r\n    try:\r\n        model_obj = ARIMA(data_loader.train_data[:, i], [30, 0, 2])\r\n        p = model_obj.predict(data_loader.test_x[:, :, i, 0])\r\n    except Exception as e:\r\n        print('Converge failed with error', e)\r\n        print('Using zero as prediction')\r\n        p = np.zeros([data_loader.test_x[:, :, i, 0].shape[0], 1, 1])\r\n\r\n    prediction.append(p)\r\n\r\n    print(np.concatenate(prediction, axis=-1).shape)\r\n\r\nprediction = np.concatenate(prediction, axis=-1)\r\n\r\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))"
  },
  {
    "path": "Experiments/ParameterSearch/CPT_GBRT.py",
    "content": "import numpy as np\nfrom UCTB.dataset import NodeTrafficLoader\nfrom sklearn.ensemble import GradientBoostingRegressor\nfrom UCTB.evaluation import metric\n\ndataset = 'ChargeStation'\ncity = 'Beijing'\n\ndata_loader = NodeTrafficLoader(dataset=dataset, city=city, with_lm=False,\n                                closeness_len=5, period_len=3, trend_len=4, test_ratio=0.1, normalize=False)\n\nprediction = []\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = GradientBoostingRegressor(n_estimators=540, max_depth=3)\n\n    train_x = np.concatenate([data_loader.train_closeness[:, 0, i, :],\n                              data_loader.train_period[:, 0, i, :],\n                              data_loader.train_trend[:, 0, i, :]], axis=-1)\n\n    test_x = np.concatenate([data_loader.test_closeness[:, 0, i, :],\n                             data_loader.test_period[:, 0, i, :],\n                             data_loader.test_trend[:, 0, i, :]], axis=-1)\n\n    model.fit(train_x, data_loader.train_y[:, i])\n\n    p = model.predict(test_x).reshape([-1, 1, 1])\n\n    prediction.append(p)\n\nprediction = np.concatenate(prediction, axis=-2)\n\nprint(dataset, city, 'RMSE', metric.rmse(prediction, data_loader.test_y))\nprint(dataset, city, 'MAPE', metric.mape(prediction, data_loader.test_y, threshold=0))\n\n\ndef show_prediction(prediction, target, station_index, start=0, end=-1):\n\n    import matplotlib.pyplot as plt\n\n    # fig, axs = plt.subplots(1, 2, figsize=(9, 3))\n    # axs[0].plot(prediction[start:end, station_index])\n    # axs[1].plot(target[start:end, station_index])\n\n    plt.plot(prediction[start:end, station_index], 'b')\n    plt.plot(target[start:end, station_index], 'r')\n\n    print(metric.rmse(prediction[start:end, station_index], target[start:end, station_index]))\n\n    print(prediction[start:end, station_index].max(), target[start:end, station_index].max())\n    print(prediction[start:end, station_index].min(), target[start:end, station_index].min())\n\n    plt.show()\n\nprint('Debug')"
  },
  {
    "path": "Experiments/ParameterSearch/CPT_HM.py",
    "content": "import nni\r\n\r\nfrom UCTB.dataset import NodeTrafficLoader\r\nfrom UCTB.model import HM\r\nfrom UCTB.evaluation import metric\r\n\r\nparams = nni.get_next_parameter()\r\n\r\ndata_loader = NodeTrafficLoader(dataset=params['Dataset'], city=params['City'], with_lm=False, normalize=False, test_ratio=0.1)\r\n\r\ntest_start_index = data_loader.traffic_data.shape[0] - data_loader.test_data.shape[0]\r\n\r\nval_start_index = data_loader.traffic_data.shape[0] - data_loader.test_data.shape[0] * 2\r\n\r\nhm_obj = HM(c=int(params['CT']), p=int(params['PT']), t=int(params['TT']))\r\n\r\nval_prediction = hm_obj.predict(val_start_index, data_loader.traffic_data[:test_start_index],\r\n                                time_fitness=data_loader.dataset.time_fitness)\r\n\r\ntest_prediction = hm_obj.predict(test_start_index, data_loader.traffic_data, time_fitness=data_loader.dataset.time_fitness)\r\n\r\nval_rmse = metric.rmse(val_prediction, data_loader.traffic_data[val_start_index: test_start_index])\r\n\r\ntest_rmse = metric.rmse(test_prediction, data_loader.test_data)\r\n\r\nprint(val_rmse, test_rmse)\r\n\r\nnni.report_final_result({\r\n    'default': val_rmse,\r\n    'test-rmse': test_rmse,\r\n})"
  },
  {
    "path": "Experiments/ParameterSearch/CPT_STMeta_Obj.py",
    "content": "import os\r\nimport nni\r\nimport numpy as np\r\n\r\nfrom UCTB.dataset import NodeTrafficLoader\r\nfrom UCTB.model import STMeta_V1\r\nfrom UCTB.evaluation import metric\r\nfrom UCTB.model_unit import GraphBuilder\r\nfrom UCTB.preprocess import is_work_day_china\r\n\r\nmodel_dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'model_dir')\r\n\r\n\r\ndef cpt_stmeta_param_parser():\r\n    import argparse\r\n    parser = argparse.ArgumentParser(description=\"Argument Parser\")\r\n    # data source\r\n    parser.add_argument('--Dataset', default='DiDi')\r\n    parser.add_argument('--City', default='Xian')\r\n    # network parameter\r\n    parser.add_argument('--CT', default='6', type=int)\r\n    parser.add_argument('--PT', default='7', type=int)\r\n    parser.add_argument('--TT', default='4', type=int)\r\n    parser.add_argument('--K', default='1', type=int)\r\n    parser.add_argument('--L', default='1', type=int)\r\n    parser.add_argument('--Graph', default='Distance-Interaction-Correlation')\r\n    parser.add_argument('--GLL', default='1', type=int)\r\n    parser.add_argument('--LSTMUnits', default='64', type=int)\r\n    parser.add_argument('--GALUnits', default='64', type=int)\r\n    parser.add_argument('--GALHeads', default='2', type=int)\r\n    parser.add_argument('--DenseUnits', default='32', type=int)\r\n    parser.add_argument('--Normalize', default='True', type=str)\r\n    # Training data parameters\r\n    parser.add_argument('--DataRange', default='All')\r\n    parser.add_argument('--TrainDays', default='All')\r\n    # Graph parameter\r\n    parser.add_argument('--TC', default='0.7', type=float)\r\n    parser.add_argument('--TD', default='3000', type=float)\r\n    parser.add_argument('--TI', default='100', type=float)\r\n    # training parameters\r\n    parser.add_argument('--Epoch', default='5000', type=int)\r\n    parser.add_argument('--Train', default='True', type=str)\r\n    parser.add_argument('--lr', default='1e-4', type=float)\r\n    parser.add_argument('--ESlength', default='200', type=int)\r\n    parser.add_argument('--patience', default='0.1', type=float)\r\n    parser.add_argument('--BatchSize', default='128', type=int)\r\n    # device parameter\r\n    parser.add_argument('--Device', default='0,1', type=str)\r\n    # version control\r\n    parser.add_argument('--Group', default='Xian')\r\n    parser.add_argument('--CodeVersion', default='ParamTuner')\r\n    return parser\r\n\r\n\r\nparser = cpt_stmeta_param_parser()\r\nargs = vars(parser.parse_args())\r\n\r\nargs.update(nni.get_next_parameter())\r\n\r\nmodel_dir = os.path.join(model_dir_path, args['Group'])\r\ncode_version = 'CPT_STMeta_{}_K{}L{}_{}'.format(''.join([e[0] for e in args['Graph'].split('-')]),\r\n                                                      args['K'], args['L'], args['CodeVersion'] + nni.get_sequence_id())\r\n\r\n# Config data loader\r\ndata_loader = NodeTrafficLoader(dataset=args['Dataset'], city=args['City'],\r\n                                  data_range=args['DataRange'], train_data_length=args['TrainDays'],\r\n                                  test_ratio=0.1,\r\n                                  C_T=int(args['CT']), P_T=int(args['PT']), T_T=int(args['TT']),\r\n                                  TI=args['TI'], TD=args['TD'], TC=args['TC'],\r\n                                  normalize=True if args['Normalize'] == 'True' else False,\r\n                                  graph=args['Graph'], with_lm=True)\r\n\r\nde_normalizer = None if args['Normalize'] == 'False' else data_loader.normalizer.min_max_denormal\r\n\r\nCPT_STMeta_Obj = STMeta_V1(num_node=data_loader.station_number,\r\n                                  num_graph=data_loader.LM.shape[0],\r\n                                  external_dim=data_loader.external_dim,\r\n                                  C_T=int(args['CT']), P_T=int(args['PT']), T_T=int(args['TT']),\r\n                                  GCN_K=int(args['K']),\r\n                                  GCN_layers=int(args['L']),\r\n                                  GCLSTM_layers=int(args['GLL']),\r\n                                  gal_units=int(args['GALUnits']),\r\n                                  gal_num_heads=int(args['GALHeads']),\r\n                                  num_hidden_units=int(args['LSTMUnits']),\r\n                                  num_filter_conv1x1=int(args['DenseUnits']),\r\n                                  lr=float(args['lr']),\r\n                                  code_version=code_version,\r\n                                  model_dir=model_dir,\r\n                                  GPU_DEVICE=args['Device'])\r\n\r\nCPT_STMeta_Obj.build()\r\n\r\nprint(args['Dataset'], args['City'], code_version)\r\nprint('Number of trainable variables', CPT_STMeta_Obj.trainable_vars)\r\n\r\n# Training\r\nif args['Train'] == 'True':\r\n    CPT_STMeta_Obj.fit(closeness_feature=data_loader.train_closeness,\r\n                       period_feature=data_loader.train_period,\r\n                       trend_feature=data_loader.train_trend,\r\n                       laplace_matrix=data_loader.LM,\r\n                       target=data_loader.train_y,\r\n                       external_feature=data_loader.train_ef,\r\n                       early_stop_method='t-test',\r\n                       early_stop_length=int(args['ESlength']),\r\n                       early_stop_patience=float(args['patience']),\r\n                       batch_size=int(args['BatchSize']),\r\n                       max_epoch=int(args['Epoch']))\r\n\r\nCPT_STMeta_Obj.load(code_version)\r\n\r\n# Evaluate\r\ntest_error = CPT_STMeta_Obj.evaluate(closeness_feature=data_loader.test_closeness,\r\n                                     period_feature=data_loader.test_period,\r\n                                     trend_feature=data_loader.test_trend,\r\n                                     laplace_matrix=data_loader.LM,\r\n                                     target=data_loader.test_y,\r\n                                     external_feature=data_loader.test_ef,\r\n                                     cache_volume=int(args['BatchSize']),\r\n                                     metrics=[metric.rmse, metric.mape],\r\n                                     de_normalizer=de_normalizer,\r\n                                     threshold=0)\r\n\r\nprint('Test result', test_error)\r\n\r\nval_loss = CPT_STMeta_Obj.load_event_scalar('val_loss')\r\n\r\nbest_val_loss = min([e[-1] for e in val_loss])\r\n\r\nnni.report_final_result({\r\n    'default': best_val_loss,\r\n    'test-rmse': test_error[0],\r\n    'test-mape': test_error[1]\r\n})\r\n"
  },
  {
    "path": "Experiments/ParameterSearch/CPT_XGBoost.py",
    "content": "import nni\r\nimport numpy as np\r\n\r\nfrom UCTB.dataset import NodeTrafficLoader_CPT, NodeTrafficLoader\r\nfrom UCTB.model import XGBoost\r\nfrom UCTB.evaluation import metric\r\n\r\nparams = {\r\n    'Dataset': 'Bike',\r\n    'City': 'NYC',\r\n    'CT': 6,\r\n    'PT': 0,\r\n    'TT': 0,\r\n    'max_depth': 10,\r\n    'num_boost_round': 150\r\n}\r\n\r\n# params.update(nni.get_next_parameter())\r\n\r\ndata_loader = NodeTrafficLoader_CPT(dataset=params['Dataset'], city=params['City'],\r\n                                    with_lm=False, test_ratio=0.1, normalize=False,\r\n                                    C_T=int(params['CT']), P_T=int(params['PT']), T_T=int(params['TT']))\r\n\r\ntest_prediction = []\r\nval_prediction = []\r\n\r\nfor i in range(data_loader.station_number):\r\n\r\n    print('*************************************************************')\r\n    print('Station', i)\r\n\r\n    model = XGBoost(max_depth=int(params['max_depth']))\r\n\r\n    train = []\r\n    test_x = []\r\n\r\n    if int(params['CT']) > 0:\r\n        train.append(data_loader.train_closeness[:, 0, i, :])\r\n        test_x.append(data_loader.test_closeness[:, 0, i, :])\r\n    if int(params['PT']) > 0:\r\n        train.append(data_loader.train_period[:, :, i, -1])\r\n        test_x.append(data_loader.test_period[:, :, i, -1])\r\n    if int(params['TT']) > 0:\r\n        train.append(data_loader.train_trend[:, :, i, -1])\r\n        test_x.append(data_loader.test_trend[:, :, i, -1])\r\n\r\n    train = np.concatenate(train, axis=-1)\r\n\r\n    test_x = np.concatenate(test_x, axis=-1)\r\n\r\n    # val has the same length as test\r\n    train_x, val_x = train[:-len(test_x)], train[-len(test_x):]\r\n\r\n    train_y, val_y = data_loader.train_y[:-len(test_x), i], data_loader.train_y[-len(test_x):, i]\r\n\r\n    model.fit(train_x, train_y, num_boost_round=int(params['num_boost_round']))\r\n\r\n    test_p = model.predict(test_x).reshape([-1, 1, 1])\r\n    val_p = model.predict(val_x).reshape([-1, 1, 1])\r\n\r\n    test_prediction.append(test_p)\r\n    val_prediction.append(val_p)\r\n\r\ntest_prediction = np.concatenate(test_prediction, axis=-2)\r\nval_prediction = np.concatenate(val_prediction, axis=-2)\r\n\r\nval_rmse = metric.rmse(val_prediction, data_loader.train_y[-len(data_loader.test_y):])\r\ntest_rmse = metric.rmse(test_prediction, data_loader.test_y)\r\n\r\n# nni.report_final_result({\r\n#     'default': val_rmse,\r\n#     'test-rmse': test_rmse,\r\n# })"
  },
  {
    "path": "Experiments/ParameterSearch/config.yml",
    "content": "authorName: DiChai\r\nexperimentName: parameter_search\r\ntrialConcurrency: 2\r\nmaxExecDuration: 24h\r\nmaxTrialNum: 50\r\ntrainingServicePlatform: local\r\n# The path to Search Space\r\nsearchSpacePath: search_space.json\r\nuseAnnotation: false\r\ntuner:\r\n  builtinTunerName: TPE\r\n# The path and the running command of trial\r\ntrial:\r\n  command: python STMeta_V0_Obj.py\r\n  codeDir: .\r\n  gpuNum: 1\r\n"
  },
  {
    "path": "Experiments/ParameterSearch/hm_config.yml",
    "content": "authorName: DiChai\r\nexperimentName: hm_parameter_search\r\ntrialConcurrency: 8\r\nmaxExecDuration: 24h\r\nmaxTrialNum: 200\r\ntrainingServicePlatform: local\r\n# The path to Search Space\r\nsearchSpacePath: hm_search_space.json\r\nuseAnnotation: false\r\ntuner:\r\n  builtinTunerName: TPE\r\n# The path and the running command of trial\r\ntrial:\r\n  command: python CPT_HM.py\r\n  codeDir: .\r\n  gpuNum: 0"
  },
  {
    "path": "Experiments/ParameterSearch/hm_search_space.json",
    "content": "{\r\n\r\n    \"Dataset\": {\"_type\": \"choice\", \"_value\": [\"Bike\"]},\r\n    \"City\": {\"_type\": \"choice\", \"_value\": [\"DC\"]},\r\n\r\n    \"CT\": {\"_type\":\"randint\",\"_value\":[0, 6]},\r\n    \"PT\": {\"_type\":\"randint\",\"_value\":[0, 7]},\r\n    \"TT\": {\"_type\":\"randint\",\"_value\":[0, 4]}\r\n}"
  },
  {
    "path": "Experiments/ParameterSearch/plot_paper.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 13,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import matplotlib.pyplot as plt\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 17,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"with open('FedMF-Full.txt', 'r', encoding='utf-8') as f:\\n\",\n    \"    fedmf_full = f.readlines()\\n\",\n    \"with open('FedMF-Part.txt', 'r', encoding='utf-8') as f:\\n\",\n    \"    fedmf_part = f.readlines()\\n\",\n    \"with open('MF.txt', 'r', encoding='utf-8') as f:\\n\",\n    \"    mf = f.readlines()\\n\",\n    \"    \\n\",\n    \"fedmf_full = [e.strip('\\\\n') for e in fedmf_full if e.startswith('loss')]\\n\",\n    \"fedmf_full = [float(e.split(' ')[-1]) for e in fedmf_full]\\n\",\n    \"\\n\",\n    \"fedmf_part = [e.strip('\\\\n') for e in fedmf_part if e.startswith('loss')]\\n\",\n    \"fedmf_part = [float(e.split(' ')[-1]) for e in fedmf_part]\\n\",\n    \"\\n\",\n    \"mf = [e.strip('\\\\n') for e in mf if e.startswith('loss')]\\n\",\n    \"mf = [float(e.split(' ')[-1]) for e in mf]\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 47,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"fig, axs = plt.subplots()\\n\",\n    \"\\n\",\n    \"axs.plot(fedmf_full, 'b+-', label='FedMF-Full', linewidth=0.5)\\n\",\n    \"axs.plot(fedmf_part, 'g.-', label='FedMF-Part', linewidth=0.5)\\n\",\n    \"axs.plot(mf, 'r-', label='Regular-MF', linewidth=0.5)\\n\",\n    \"\\n\",\n    \"axs.grid()\\n\",\n    \"axs.legend(fontsize=15)\\n\",\n    \"\\n\",\n    \"axs.set_xlabel('Epochs', fontsize=15)\\n\",\n    \"axs.set_ylabel('Train Loss', fontsize=15)\\n\",\n    \"\\n\",\n    \"fig.set_size_inches(10, 5)\\n\",\n    \"fig.savefig('%s.png' % 'comparison', dpi=100)\\n\",\n    \"plt.close()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.5.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"
  },
  {
    "path": "Experiments/ParameterSearch/results/HM_Bike_NYC.json",
    "content": "{\r\n    \"experimentParameters\": {\r\n        \"id\": \"rU6J0i83\",\r\n        \"revision\": 287,\r\n        \"execDuration\": 854,\r\n        \"logDir\": \"/Users/chaidi/nni/experiments/rU6J0i83\",\r\n        \"maxSequenceId\": 199,\r\n        \"params\": {\r\n            \"authorName\": \"DiChai\",\r\n            \"experimentName\": \"hm_parameter_search\",\r\n            \"trialConcurrency\": 8,\r\n            \"maxExecDuration\": 86400,\r\n            \"maxTrialNum\": 200,\r\n            \"searchSpace\": {\r\n                \"Dataset\": {\r\n                    \"_type\": \"choice\",\r\n                    \"_value\": [\r\n                        \"Bike\"\r\n                    ]\r\n                },\r\n                \"City\": {\r\n                    \"_type\": \"choice\",\r\n                    \"_value\": [\r\n                        \"NYC\"\r\n                    ]\r\n                },\r\n                \"CT\": {\r\n                    \"_type\": \"randint\",\r\n                    \"_value\": [\r\n                        0,\r\n                        6\r\n                    ]\r\n                },\r\n                \"PT\": {\r\n                    \"_type\": \"randint\",\r\n                    \"_value\": [\r\n                        0,\r\n                        7\r\n                    ]\r\n                },\r\n                \"TT\": {\r\n                    \"_type\": \"randint\",\r\n                    \"_value\": [\r\n                        0,\r\n                        4\r\n                    ]\r\n                }\r\n            },\r\n            \"trainingServicePlatform\": \"local\",\r\n            \"tuner\": {\r\n                \"builtinTunerName\": \"TPE\",\r\n                \"className\": \"TPE\",\r\n                \"checkpointDir\": \"/Users/chaidi/nni/experiments/rU6J0i83/checkpoint\"\r\n            },\r\n            \"versionCheck\": true,\r\n            \"clusterMetaData\": [\r\n                {\r\n                    \"key\": \"codeDir\",\r\n                    \"value\": \"/Users/chaidi/Documents/UCTB-Package-0.0.5/Experiments/ParameterSearch/.\"\r\n                },\r\n                {\r\n                    \"key\": \"command\",\r\n                    \"value\": \"python CPT_HM.py\"\r\n                }\r\n            ]\r\n        },\r\n        \"startTime\": 1560834878927,\r\n        \"endTime\": 1560835756258\r\n    },\r\n    \"trialMessage\": [\r\n        {\r\n            \"id\": \"TVG5A\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 0,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 7,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/TVG5A\",\r\n            \"startTime\": 1560834888962,\r\n            \"sequenceId\": 0,\r\n            \"endTime\": 1560834916000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834914905,\r\n                    \"trialJobId\": \"TVG5A\",\r\n                    \"parameterId\": \"0\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3573408463670296,\\\"test-rmse\\\":4.4766049838814865}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834914905,\r\n                    \"trialJobId\": \"TVG5A\",\r\n                    \"parameterId\": \"0\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3573408463670296,\\\"test-rmse\\\":4.4766049838814865}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"VRzdk\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 1,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 6,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/VRzdk\",\r\n            \"startTime\": 1560834888984,\r\n            \"sequenceId\": 1,\r\n            \"endTime\": 1560834915000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834914328,\r\n                    \"trialJobId\": \"VRzdk\",\r\n                    \"parameterId\": \"1\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3343664050554174,\\\"test-rmse\\\":4.36618297262181}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834914328,\r\n                    \"trialJobId\": \"VRzdk\",\r\n                    \"parameterId\": \"1\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3343664050554174,\\\"test-rmse\\\":4.36618297262181}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"lOmsf\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 2,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 4,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/lOmsf\",\r\n            \"startTime\": 1560834889005,\r\n            \"sequenceId\": 2,\r\n            \"endTime\": 1560834915000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834914658,\r\n                    \"trialJobId\": \"lOmsf\",\r\n                    \"parameterId\": \"2\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.572369188547026,\\\"test-rmse\\\":4.910039558096488}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834914658,\r\n                    \"trialJobId\": \"lOmsf\",\r\n                    \"parameterId\": \"2\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.572369188547026,\\\"test-rmse\\\":4.910039558096488}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"KMdKS\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 3,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 4,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/KMdKS\",\r\n            \"startTime\": 1560834889027,\r\n            \"sequenceId\": 3,\r\n            \"endTime\": 1560834916000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834915208,\r\n                    \"trialJobId\": \"KMdKS\",\r\n                    \"parameterId\": \"3\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7734189500775583,\\\"test-rmse\\\":5.260572896761711}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834915208,\r\n                    \"trialJobId\": \"KMdKS\",\r\n                    \"parameterId\": \"3\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7734189500775583,\\\"test-rmse\\\":5.260572896761711}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"nlasg\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 4,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 4,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/nlasg\",\r\n            \"startTime\": 1560834889049,\r\n            \"sequenceId\": 4,\r\n            \"endTime\": 1560834916000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834915414,\r\n                    \"trialJobId\": \"nlasg\",\r\n                    \"parameterId\": \"4\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2491156358278035,\\\"test-rmse\\\":4.294810041672708}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834915414,\r\n                    \"trialJobId\": \"nlasg\",\r\n                    \"parameterId\": \"4\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2491156358278035,\\\"test-rmse\\\":4.294810041672708}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"kiJSj\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 5,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 5,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/kiJSj\",\r\n            \"startTime\": 1560834889076,\r\n            \"sequenceId\": 5,\r\n            \"endTime\": 1560834916000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834915122,\r\n                    \"trialJobId\": \"kiJSj\",\r\n                    \"parameterId\": \"5\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.466012234112674,\\\"test-rmse\\\":4.607805766719761}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834915122,\r\n                    \"trialJobId\": \"kiJSj\",\r\n                    \"parameterId\": \"5\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.466012234112674,\\\"test-rmse\\\":4.607805766719761}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"gLmN4\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 6,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 7,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/gLmN4\",\r\n            \"startTime\": 1560834889111,\r\n            \"sequenceId\": 6,\r\n            \"endTime\": 1560834916000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834915509,\r\n                    \"trialJobId\": \"gLmN4\",\r\n                    \"parameterId\": \"6\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3004494216603684,\\\"test-rmse\\\":4.361940866064909}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834915509,\r\n                    \"trialJobId\": \"gLmN4\",\r\n                    \"parameterId\": \"6\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3004494216603684,\\\"test-rmse\\\":4.361940866064909}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"dq52J\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 7,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 0,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/dq52J\",\r\n            \"startTime\": 1560834889149,\r\n            \"sequenceId\": 7,\r\n            \"endTime\": 1560834916000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834915194,\r\n                    \"trialJobId\": \"dq52J\",\r\n                    \"parameterId\": \"7\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.538208791457419,\\\"test-rmse\\\":4.822044041480414}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834915194,\r\n                    \"trialJobId\": \"dq52J\",\r\n                    \"parameterId\": \"7\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.538208791457419,\\\"test-rmse\\\":4.822044041480414}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"EJ12u\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 8,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 0,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/EJ12u\",\r\n            \"startTime\": 1560834929194,\r\n            \"sequenceId\": 8,\r\n            \"endTime\": 1560834959000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834958287,\r\n                    \"trialJobId\": \"EJ12u\",\r\n                    \"parameterId\": \"8\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5191010428127005,\\\"test-rmse\\\":4.81101214229983}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834958287,\r\n                    \"trialJobId\": \"EJ12u\",\r\n                    \"parameterId\": \"8\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5191010428127005,\\\"test-rmse\\\":4.81101214229983}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"IS6ox\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 9,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/IS6ox\",\r\n            \"startTime\": 1560834929213,\r\n            \"sequenceId\": 9,\r\n            \"endTime\": 1560834959000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834958697,\r\n                    \"trialJobId\": \"IS6ox\",\r\n                    \"parameterId\": \"9\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4802802810775693,\\\"test-rmse\\\":4.767764316499411}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834958697,\r\n                    \"trialJobId\": \"IS6ox\",\r\n                    \"parameterId\": \"9\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4802802810775693,\\\"test-rmse\\\":4.767764316499411}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"j7ezD\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 10,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 0,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/j7ezD\",\r\n            \"startTime\": 1560834929233,\r\n            \"sequenceId\": 10,\r\n            \"endTime\": 1560834959000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834958473,\r\n                    \"trialJobId\": \"j7ezD\",\r\n                    \"parameterId\": \"10\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.9931763530716755,\\\"test-rmse\\\":5.645536720983396}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834958473,\r\n                    \"trialJobId\": \"j7ezD\",\r\n                    \"parameterId\": \"10\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.9931763530716755,\\\"test-rmse\\\":5.645536720983396}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"bqWYD\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 11,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 6,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/bqWYD\",\r\n            \"startTime\": 1560834929254,\r\n            \"sequenceId\": 11,\r\n            \"endTime\": 1560834959000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834958536,\r\n                    \"trialJobId\": \"bqWYD\",\r\n                    \"parameterId\": \"11\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4135064227648066,\\\"test-rmse\\\":4.593027637181522}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834958536,\r\n                    \"trialJobId\": \"bqWYD\",\r\n                    \"parameterId\": \"11\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4135064227648066,\\\"test-rmse\\\":4.593027637181522}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"HUF36\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 12,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 7,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/HUF36\",\r\n            \"startTime\": 1560834929277,\r\n            \"sequenceId\": 12,\r\n            \"endTime\": 1560834959000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834958902,\r\n                    \"trialJobId\": \"HUF36\",\r\n                    \"parameterId\": \"12\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2535923832312394,\\\"test-rmse\\\":4.283320320090695}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834958902,\r\n                    \"trialJobId\": \"HUF36\",\r\n                    \"parameterId\": \"12\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2535923832312394,\\\"test-rmse\\\":4.283320320090695}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"yF9e5\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 13,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 0,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/yF9e5\",\r\n            \"startTime\": 1560834929301,\r\n            \"sequenceId\": 13,\r\n            \"endTime\": 1560834958000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834957395,\r\n                    \"trialJobId\": \"yF9e5\",\r\n                    \"parameterId\": \"13\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.75877939072391,\\\"test-rmse\\\":4.573542776546816}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834957395,\r\n                    \"trialJobId\": \"yF9e5\",\r\n                    \"parameterId\": \"13\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.75877939072391,\\\"test-rmse\\\":4.573542776546816}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"RVjef\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 14,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 4,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/RVjef\",\r\n            \"startTime\": 1560834929332,\r\n            \"sequenceId\": 14,\r\n            \"endTime\": 1560834959000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834958810,\r\n                    \"trialJobId\": \"RVjef\",\r\n                    \"parameterId\": \"14\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2600343679445145,\\\"test-rmse\\\":4.31781077879459}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834958810,\r\n                    \"trialJobId\": \"RVjef\",\r\n                    \"parameterId\": \"14\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2600343679445145,\\\"test-rmse\\\":4.31781077879459}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"JhLvu\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 15,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 6,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/JhLvu\",\r\n            \"startTime\": 1560834929360,\r\n            \"sequenceId\": 15,\r\n            \"endTime\": 1560834959000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834958937,\r\n                    \"trialJobId\": \"JhLvu\",\r\n                    \"parameterId\": \"15\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4830314962014395,\\\"test-rmse\\\":4.72193178462408}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834958937,\r\n                    \"trialJobId\": \"JhLvu\",\r\n                    \"parameterId\": \"15\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4830314962014395,\\\"test-rmse\\\":4.72193178462408}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"sJsVd\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 16,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 1,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/sJsVd\",\r\n            \"startTime\": 1560834969417,\r\n            \"sequenceId\": 16,\r\n            \"endTime\": 1560834998000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834997694,\r\n                    \"trialJobId\": \"sJsVd\",\r\n                    \"parameterId\": \"16\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.174530800023379,\\\"test-rmse\\\":4.231832613503912}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834997694,\r\n                    \"trialJobId\": \"sJsVd\",\r\n                    \"parameterId\": \"16\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.174530800023379,\\\"test-rmse\\\":4.231832613503912}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"gWvRN\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 17,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/gWvRN\",\r\n            \"startTime\": 1560834969437,\r\n            \"sequenceId\": 17,\r\n            \"endTime\": 1560834998000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834998068,\r\n                    \"trialJobId\": \"gWvRN\",\r\n                    \"parameterId\": \"17\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2394669627302033,\\\"test-rmse\\\":4.3386627034250544}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834998068,\r\n                    \"trialJobId\": \"gWvRN\",\r\n                    \"parameterId\": \"17\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2394669627302033,\\\"test-rmse\\\":4.3386627034250544}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"ycNyp\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 18,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 2,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/ycNyp\",\r\n            \"startTime\": 1560834969462,\r\n            \"sequenceId\": 18,\r\n            \"endTime\": 1560834998000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834997900,\r\n                    \"trialJobId\": \"ycNyp\",\r\n                    \"parameterId\": \"18\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.198500385778617,\\\"test-rmse\\\":4.269447689696311}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834997900,\r\n                    \"trialJobId\": \"ycNyp\",\r\n                    \"parameterId\": \"18\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.198500385778617,\\\"test-rmse\\\":4.269447689696311}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"EannN\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 19,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 1,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/EannN\",\r\n            \"startTime\": 1560834969483,\r\n            \"sequenceId\": 19,\r\n            \"endTime\": 1560834998000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834997552,\r\n                    \"trialJobId\": \"EannN\",\r\n                    \"parameterId\": \"19\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4458378991034095,\\\"test-rmse\\\":4.681977149225176}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834997552,\r\n                    \"trialJobId\": \"EannN\",\r\n                    \"parameterId\": \"19\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4458378991034095,\\\"test-rmse\\\":4.681977149225176}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"rcJZn\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 20,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 1,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/rcJZn\",\r\n            \"startTime\": 1560834969505,\r\n            \"sequenceId\": 20,\r\n            \"endTime\": 1560834995000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834995399,\r\n                    \"trialJobId\": \"rcJZn\",\r\n                    \"parameterId\": \"20\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.504996080310306,\\\"test-rmse\\\":4.8344830263132454}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834995399,\r\n                    \"trialJobId\": \"rcJZn\",\r\n                    \"parameterId\": \"20\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.504996080310306,\\\"test-rmse\\\":4.8344830263132454}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"ubfna\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 21,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 6,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/ubfna\",\r\n            \"startTime\": 1560834969533,\r\n            \"sequenceId\": 21,\r\n            \"endTime\": 1560834995000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834995465,\r\n                    \"trialJobId\": \"ubfna\",\r\n                    \"parameterId\": \"21\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.374924096159413,\\\"test-rmse\\\":4.499867384060287}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834995465,\r\n                    \"trialJobId\": \"ubfna\",\r\n                    \"parameterId\": \"21\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.374924096159413,\\\"test-rmse\\\":4.499867384060287}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"hur1q\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 22,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 6,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/hur1q\",\r\n            \"startTime\": 1560834969561,\r\n            \"sequenceId\": 22,\r\n            \"endTime\": 1560834996000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834995984,\r\n                    \"trialJobId\": \"hur1q\",\r\n                    \"parameterId\": \"22\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4155997077622158,\\\"test-rmse\\\":4.5115602918049245}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834995984,\r\n                    \"trialJobId\": \"hur1q\",\r\n                    \"parameterId\": \"22\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4155997077622158,\\\"test-rmse\\\":4.5115602918049245}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"jITeW\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 23,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 1,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/jITeW\",\r\n            \"startTime\": 1560834969600,\r\n            \"sequenceId\": 23,\r\n            \"endTime\": 1560834998000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560834998191,\r\n                    \"trialJobId\": \"jITeW\",\r\n                    \"parameterId\": \"23\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.326027762112886,\\\"test-rmse\\\":4.462921330678163}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560834998191,\r\n                    \"trialJobId\": \"jITeW\",\r\n                    \"parameterId\": \"23\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.326027762112886,\\\"test-rmse\\\":4.462921330678163}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"mGgz7\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 24,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 2,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/mGgz7\",\r\n            \"startTime\": 1560835009647,\r\n            \"sequenceId\": 24,\r\n            \"endTime\": 1560835039000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835038166,\r\n                    \"trialJobId\": \"mGgz7\",\r\n                    \"parameterId\": \"24\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.1456571550914285,\\\"test-rmse\\\":5.5935759980114845}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835038166,\r\n                    \"trialJobId\": \"mGgz7\",\r\n                    \"parameterId\": \"24\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.1456571550914285,\\\"test-rmse\\\":5.5935759980114845}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"LTXqu\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 25,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 6,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/LTXqu\",\r\n            \"startTime\": 1560835009668,\r\n            \"sequenceId\": 25,\r\n            \"endTime\": 1560835039000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835038662,\r\n                    \"trialJobId\": \"LTXqu\",\r\n                    \"parameterId\": \"25\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2749368288289036,\\\"test-rmse\\\":4.272061981362897}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835038662,\r\n                    \"trialJobId\": \"LTXqu\",\r\n                    \"parameterId\": \"25\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2749368288289036,\\\"test-rmse\\\":4.272061981362897}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"u6PZc\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 26,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 2,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/u6PZc\",\r\n            \"startTime\": 1560835009687,\r\n            \"sequenceId\": 26,\r\n            \"endTime\": 1560835039000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835038518,\r\n                    \"trialJobId\": \"u6PZc\",\r\n                    \"parameterId\": \"26\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.510327263886997,\\\"test-rmse\\\":4.87863065242511}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835038518,\r\n                    \"trialJobId\": \"u6PZc\",\r\n                    \"parameterId\": \"26\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.510327263886997,\\\"test-rmse\\\":4.87863065242511}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"lZu4x\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 27,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 1,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/lZu4x\",\r\n            \"startTime\": 1560835009707,\r\n            \"sequenceId\": 27,\r\n            \"endTime\": 1560835039000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835038598,\r\n                    \"trialJobId\": \"lZu4x\",\r\n                    \"parameterId\": \"27\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.852152225593427,\\\"test-rmse\\\":5.457018020376654}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835038598,\r\n                    \"trialJobId\": \"lZu4x\",\r\n                    \"parameterId\": \"27\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.852152225593427,\\\"test-rmse\\\":5.457018020376654}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"wHCrC\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 28,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 2,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/wHCrC\",\r\n            \"startTime\": 1560835009731,\r\n            \"sequenceId\": 28,\r\n            \"endTime\": 1560835039000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835038045,\r\n                    \"trialJobId\": \"wHCrC\",\r\n                    \"parameterId\": \"28\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2679195534286474,\\\"test-rmse\\\":4.363781360262389}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835038045,\r\n                    \"trialJobId\": \"wHCrC\",\r\n                    \"parameterId\": \"28\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2679195534286474,\\\"test-rmse\\\":4.363781360262389}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Rrxjn\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 29,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 2,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Rrxjn\",\r\n            \"startTime\": 1560835009756,\r\n            \"sequenceId\": 29,\r\n            \"endTime\": 1560835039000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835037953,\r\n                    \"trialJobId\": \"Rrxjn\",\r\n                    \"parameterId\": \"29\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.439568822782419,\\\"test-rmse\\\":4.744079418261335}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835037953,\r\n                    \"trialJobId\": \"Rrxjn\",\r\n                    \"parameterId\": \"29\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.439568822782419,\\\"test-rmse\\\":4.744079418261335}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"NOwsq\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 30,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 4,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/NOwsq\",\r\n            \"startTime\": 1560835009783,\r\n            \"sequenceId\": 30,\r\n            \"endTime\": 1560835039000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835038679,\r\n                    \"trialJobId\": \"NOwsq\",\r\n                    \"parameterId\": \"30\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.27106570357587,\\\"test-rmse\\\":4.277377402673887}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835038679,\r\n                    \"trialJobId\": \"NOwsq\",\r\n                    \"parameterId\": \"30\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.27106570357587,\\\"test-rmse\\\":4.277377402673887}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"bYioj\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 31,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 5,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/bYioj\",\r\n            \"startTime\": 1560835009811,\r\n            \"sequenceId\": 31,\r\n            \"endTime\": 1560835039000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835038775,\r\n                    \"trialJobId\": \"bYioj\",\r\n                    \"parameterId\": \"31\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2969113404009023,\\\"test-rmse\\\":4.310629315133367}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835038775,\r\n                    \"trialJobId\": \"bYioj\",\r\n                    \"parameterId\": \"31\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2969113404009023,\\\"test-rmse\\\":4.310629315133367}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"gkrk1\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 32,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 3,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/gkrk1\",\r\n            \"startTime\": 1560835049847,\r\n            \"sequenceId\": 32,\r\n            \"endTime\": 1560835079000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835078738,\r\n                    \"trialJobId\": \"gkrk1\",\r\n                    \"parameterId\": \"32\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.1024699784676955,\\\"test-rmse\\\":5.533757294431969}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835078738,\r\n                    \"trialJobId\": \"gkrk1\",\r\n                    \"parameterId\": \"32\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.1024699784676955,\\\"test-rmse\\\":5.533757294431969}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"oohIS\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 33,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 2,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/oohIS\",\r\n            \"startTime\": 1560835049867,\r\n            \"sequenceId\": 33,\r\n            \"endTime\": 1560835079000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835079240,\r\n                    \"trialJobId\": \"oohIS\",\r\n                    \"parameterId\": \"33\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.738915568304841,\\\"test-rmse\\\":5.254927444881956}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835079240,\r\n                    \"trialJobId\": \"oohIS\",\r\n                    \"parameterId\": \"33\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.738915568304841,\\\"test-rmse\\\":5.254927444881956}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"BgB1I\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 34,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 1,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/BgB1I\",\r\n            \"startTime\": 1560835049887,\r\n            \"sequenceId\": 34,\r\n            \"endTime\": 1560835079000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835079281,\r\n                    \"trialJobId\": \"BgB1I\",\r\n                    \"parameterId\": \"34\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.128143083616128,\\\"test-rmse\\\":4.052596168487852}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835079281,\r\n                    \"trialJobId\": \"BgB1I\",\r\n                    \"parameterId\": \"34\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.128143083616128,\\\"test-rmse\\\":4.052596168487852}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Dysz6\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 35,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 7,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Dysz6\",\r\n            \"startTime\": 1560835049909,\r\n            \"sequenceId\": 35,\r\n            \"endTime\": 1560835078000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835077429,\r\n                    \"trialJobId\": \"Dysz6\",\r\n                    \"parameterId\": \"35\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3715454534088765,\\\"test-rmse\\\":4.510303906855892}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835077429,\r\n                    \"trialJobId\": \"Dysz6\",\r\n                    \"parameterId\": \"35\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3715454534088765,\\\"test-rmse\\\":4.510303906855892}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"K1VKR\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 36,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 1,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/K1VKR\",\r\n            \"startTime\": 1560835049931,\r\n            \"sequenceId\": 36,\r\n            \"endTime\": 1560835079000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835079196,\r\n                    \"trialJobId\": \"K1VKR\",\r\n                    \"parameterId\": \"36\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.852152225593427,\\\"test-rmse\\\":5.457018020376654}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835079196,\r\n                    \"trialJobId\": \"K1VKR\",\r\n                    \"parameterId\": \"36\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.852152225593427,\\\"test-rmse\\\":5.457018020376654}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"kikmZ\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 37,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 3,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/kikmZ\",\r\n            \"startTime\": 1560835049956,\r\n            \"sequenceId\": 37,\r\n            \"endTime\": 1560835079000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835078942,\r\n                    \"trialJobId\": \"kikmZ\",\r\n                    \"parameterId\": \"37\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5406246816469817,\\\"test-rmse\\\":4.88179480853287}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835078942,\r\n                    \"trialJobId\": \"kikmZ\",\r\n                    \"parameterId\": \"37\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5406246816469817,\\\"test-rmse\\\":4.88179480853287}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"XVI3v\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 38,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 3,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/XVI3v\",\r\n            \"startTime\": 1560835049986,\r\n            \"sequenceId\": 38,\r\n            \"endTime\": 1560835080000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835079364,\r\n                    \"trialJobId\": \"XVI3v\",\r\n                    \"parameterId\": \"38\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3651437135487714,\\\"test-rmse\\\":4.552893761545617}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835079364,\r\n                    \"trialJobId\": \"XVI3v\",\r\n                    \"parameterId\": \"38\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3651437135487714,\\\"test-rmse\\\":4.552893761545617}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"qlM5l\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 39,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 0,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/qlM5l\",\r\n            \"startTime\": 1560835050024,\r\n            \"sequenceId\": 39,\r\n            \"endTime\": 1560835079000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835079101,\r\n                    \"trialJobId\": \"qlM5l\",\r\n                    \"parameterId\": \"39\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.9931763530716755,\\\"test-rmse\\\":5.645536720983396}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835079101,\r\n                    \"trialJobId\": \"qlM5l\",\r\n                    \"parameterId\": \"39\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.9931763530716755,\\\"test-rmse\\\":5.645536720983396}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"l0pZA\",\r\n            \"status\": \"FAILED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 40,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 0,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/l0pZA\",\r\n            \"startTime\": 1560835090068,\r\n            \"sequenceId\": 40,\r\n            \"endTime\": 1560835114000,\r\n            \"stderrPath\": \"file:/localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/l0pZA/stderr\",\r\n            \"intermediate\": []\r\n        },\r\n        {\r\n            \"id\": \"TUYHu\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 41,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 4,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/TUYHu\",\r\n            \"startTime\": 1560835090090,\r\n            \"sequenceId\": 41,\r\n            \"endTime\": 1560835117000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835117138,\r\n                    \"trialJobId\": \"TUYHu\",\r\n                    \"parameterId\": \"41\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.314260476911382,\\\"test-rmse\\\":4.41377705150065}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835117138,\r\n                    \"trialJobId\": \"TUYHu\",\r\n                    \"parameterId\": \"41\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.314260476911382,\\\"test-rmse\\\":4.41377705150065}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"PryD0\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 42,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 6,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/PryD0\",\r\n            \"startTime\": 1560835090113,\r\n            \"sequenceId\": 42,\r\n            \"endTime\": 1560835118000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835117445,\r\n                    \"trialJobId\": \"PryD0\",\r\n                    \"parameterId\": \"42\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5895535482445213,\\\"test-rmse\\\":4.922536211408551}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835117445,\r\n                    \"trialJobId\": \"PryD0\",\r\n                    \"parameterId\": \"42\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5895535482445213,\\\"test-rmse\\\":4.922536211408551}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"EeIsO\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 43,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/EeIsO\",\r\n            \"startTime\": 1560835090136,\r\n            \"sequenceId\": 43,\r\n            \"endTime\": 1560835117000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835116996,\r\n                    \"trialJobId\": \"EeIsO\",\r\n                    \"parameterId\": \"43\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.143210529033562,\\\"test-rmse\\\":4.0775311955434965}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835116996,\r\n                    \"trialJobId\": \"EeIsO\",\r\n                    \"parameterId\": \"43\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.143210529033562,\\\"test-rmse\\\":4.0775311955434965}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"jNLSp\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 44,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 6,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/jNLSp\",\r\n            \"startTime\": 1560835090161,\r\n            \"sequenceId\": 44,\r\n            \"endTime\": 1560835117000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835116497,\r\n                    \"trialJobId\": \"jNLSp\",\r\n                    \"parameterId\": \"44\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3343664050554174,\\\"test-rmse\\\":4.36618297262181}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835116497,\r\n                    \"trialJobId\": \"jNLSp\",\r\n                    \"parameterId\": \"44\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3343664050554174,\\\"test-rmse\\\":4.36618297262181}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"oed9t\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 45,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 6,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/oed9t\",\r\n            \"startTime\": 1560835090186,\r\n            \"sequenceId\": 45,\r\n            \"endTime\": 1560835117000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835117175,\r\n                    \"trialJobId\": \"oed9t\",\r\n                    \"parameterId\": \"45\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4155997077622158,\\\"test-rmse\\\":4.5115602918049245}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835117175,\r\n                    \"trialJobId\": \"oed9t\",\r\n                    \"parameterId\": \"45\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4155997077622158,\\\"test-rmse\\\":4.5115602918049245}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Q97Rg\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 46,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 1,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Q97Rg\",\r\n            \"startTime\": 1560835090214,\r\n            \"sequenceId\": 46,\r\n            \"endTime\": 1560835118000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835117675,\r\n                    \"trialJobId\": \"Q97Rg\",\r\n                    \"parameterId\": \"46\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.24905460598976,\\\"test-rmse\\\":4.353696152243672}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835117675,\r\n                    \"trialJobId\": \"Q97Rg\",\r\n                    \"parameterId\": \"46\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.24905460598976,\\\"test-rmse\\\":4.353696152243672}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"XzW4m\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 47,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 3,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/XzW4m\",\r\n            \"startTime\": 1560835090250,\r\n            \"sequenceId\": 47,\r\n            \"endTime\": 1560835118000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835117860,\r\n                    \"trialJobId\": \"XzW4m\",\r\n                    \"parameterId\": \"47\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2280741210519044,\\\"test-rmse\\\":4.279047811213757}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835117860,\r\n                    \"trialJobId\": \"XzW4m\",\r\n                    \"parameterId\": \"47\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2280741210519044,\\\"test-rmse\\\":4.279047811213757}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"LtNE7\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 48,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 3,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/LtNE7\",\r\n            \"startTime\": 1560835125297,\r\n            \"sequenceId\": 48,\r\n            \"endTime\": 1560835145000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835144911,\r\n                    \"trialJobId\": \"LtNE7\",\r\n                    \"parameterId\": \"48\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3595986180381825,\\\"test-rmse\\\":4.2879948237276775}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835144911,\r\n                    \"trialJobId\": \"LtNE7\",\r\n                    \"parameterId\": \"48\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3595986180381825,\\\"test-rmse\\\":4.2879948237276775}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"YoihJ\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 49,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 5,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/YoihJ\",\r\n            \"startTime\": 1560835125318,\r\n            \"sequenceId\": 49,\r\n            \"endTime\": 1560835145000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835145149,\r\n                    \"trialJobId\": \"YoihJ\",\r\n                    \"parameterId\": \"49\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5376025649718303,\\\"test-rmse\\\":4.8234107082146}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835145149,\r\n                    \"trialJobId\": \"YoihJ\",\r\n                    \"parameterId\": \"49\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5376025649718303,\\\"test-rmse\\\":4.8234107082146}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"QE5N6\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 50,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 5,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/QE5N6\",\r\n            \"startTime\": 1560835130345,\r\n            \"sequenceId\": 50,\r\n            \"endTime\": 1560835153000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835152445,\r\n                    \"trialJobId\": \"QE5N6\",\r\n                    \"parameterId\": \"50\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.403038042821588,\\\"test-rmse\\\":4.3827745135950575}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835152445,\r\n                    \"trialJobId\": \"QE5N6\",\r\n                    \"parameterId\": \"50\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.403038042821588,\\\"test-rmse\\\":4.3827745135950575}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"iO650\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 51,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 6,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/iO650\",\r\n            \"startTime\": 1560835130368,\r\n            \"sequenceId\": 51,\r\n            \"endTime\": 1560835153000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835152861,\r\n                    \"trialJobId\": \"iO650\",\r\n                    \"parameterId\": \"51\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4934787682044552,\\\"test-rmse\\\":4.741046945165195}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835152861,\r\n                    \"trialJobId\": \"iO650\",\r\n                    \"parameterId\": \"51\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4934787682044552,\\\"test-rmse\\\":4.741046945165195}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"rSkHw\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 52,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 3,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/rSkHw\",\r\n            \"startTime\": 1560835130430,\r\n            \"sequenceId\": 52,\r\n            \"endTime\": 1560835153000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835152523,\r\n                    \"trialJobId\": \"rSkHw\",\r\n                    \"parameterId\": \"52\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8068739925123705,\\\"test-rmse\\\":5.347009006462152}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835152523,\r\n                    \"trialJobId\": \"rSkHw\",\r\n                    \"parameterId\": \"52\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8068739925123705,\\\"test-rmse\\\":5.347009006462152}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"LpeJ6\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 53,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 5,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/LpeJ6\",\r\n            \"startTime\": 1560835130460,\r\n            \"sequenceId\": 53,\r\n            \"endTime\": 1560835153000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835152835,\r\n                    \"trialJobId\": \"LpeJ6\",\r\n                    \"parameterId\": \"53\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5376025649718303,\\\"test-rmse\\\":4.8234107082146}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835152835,\r\n                    \"trialJobId\": \"LpeJ6\",\r\n                    \"parameterId\": \"53\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5376025649718303,\\\"test-rmse\\\":4.8234107082146}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"AexJ2\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 54,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 5,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/AexJ2\",\r\n            \"startTime\": 1560835130489,\r\n            \"sequenceId\": 54,\r\n            \"endTime\": 1560835153000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835152468,\r\n                    \"trialJobId\": \"AexJ2\",\r\n                    \"parameterId\": \"54\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4208039705028863,\\\"test-rmse\\\":4.592784722139947}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835152468,\r\n                    \"trialJobId\": \"AexJ2\",\r\n                    \"parameterId\": \"54\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4208039705028863,\\\"test-rmse\\\":4.592784722139947}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"UVlRv\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 55,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 5,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/UVlRv\",\r\n            \"startTime\": 1560835130525,\r\n            \"sequenceId\": 55,\r\n            \"endTime\": 1560835153000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835152853,\r\n                    \"trialJobId\": \"UVlRv\",\r\n                    \"parameterId\": \"55\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.236211458500518,\\\"test-rmse\\\":4.241907734197994}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835152853,\r\n                    \"trialJobId\": \"UVlRv\",\r\n                    \"parameterId\": \"55\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.236211458500518,\\\"test-rmse\\\":4.241907734197994}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Rvsbz\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 56,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 0,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Rvsbz\",\r\n            \"startTime\": 1560835155560,\r\n            \"sequenceId\": 56,\r\n            \"endTime\": 1560835170000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835169391,\r\n                    \"trialJobId\": \"Rvsbz\",\r\n                    \"parameterId\": \"56\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.568395256921387,\\\"test-rmse\\\":4.283746354809079}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835169391,\r\n                    \"trialJobId\": \"Rvsbz\",\r\n                    \"parameterId\": \"56\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.568395256921387,\\\"test-rmse\\\":4.283746354809079}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Ny6Gz\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 57,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 0,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Ny6Gz\",\r\n            \"startTime\": 1560835155582,\r\n            \"sequenceId\": 57,\r\n            \"endTime\": 1560835170000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835169508,\r\n                    \"trialJobId\": \"Ny6Gz\",\r\n                    \"parameterId\": \"57\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.231388327725954,\\\"test-rmse\\\":4.143207316552948}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835169508,\r\n                    \"trialJobId\": \"Ny6Gz\",\r\n                    \"parameterId\": \"57\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.231388327725954,\\\"test-rmse\\\":4.143207316552948}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"nYMm4\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 58,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 3,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/nYMm4\",\r\n            \"startTime\": 1560835165608,\r\n            \"sequenceId\": 58,\r\n            \"endTime\": 1560835186000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835186166,\r\n                    \"trialJobId\": \"nYMm4\",\r\n                    \"parameterId\": \"58\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8068739925123705,\\\"test-rmse\\\":5.347009006462152}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835186166,\r\n                    \"trialJobId\": \"nYMm4\",\r\n                    \"parameterId\": \"58\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8068739925123705,\\\"test-rmse\\\":5.347009006462152}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"uXymM\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 59,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 5,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/uXymM\",\r\n            \"startTime\": 1560835165630,\r\n            \"sequenceId\": 59,\r\n            \"endTime\": 1560835187000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835186713,\r\n                    \"trialJobId\": \"uXymM\",\r\n                    \"parameterId\": \"59\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7256037776874718,\\\"test-rmse\\\":5.1637762968733885}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835186713,\r\n                    \"trialJobId\": \"uXymM\",\r\n                    \"parameterId\": \"59\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7256037776874718,\\\"test-rmse\\\":5.1637762968733885}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"w7GbG\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 60,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 1,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/w7GbG\",\r\n            \"startTime\": 1560835165655,\r\n            \"sequenceId\": 60,\r\n            \"endTime\": 1560835187000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835186383,\r\n                    \"trialJobId\": \"w7GbG\",\r\n                    \"parameterId\": \"60\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.504996080310306,\\\"test-rmse\\\":4.8344830263132454}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835186383,\r\n                    \"trialJobId\": \"w7GbG\",\r\n                    \"parameterId\": \"60\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.504996080310306,\\\"test-rmse\\\":4.8344830263132454}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"yT4DV\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 61,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 6,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/yT4DV\",\r\n            \"startTime\": 1560835165680,\r\n            \"sequenceId\": 61,\r\n            \"endTime\": 1560835187000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835186688,\r\n                    \"trialJobId\": \"yT4DV\",\r\n                    \"parameterId\": \"61\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3693117875455716,\\\"test-rmse\\\":4.517337363894021}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835186688,\r\n                    \"trialJobId\": \"yT4DV\",\r\n                    \"parameterId\": \"61\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3693117875455716,\\\"test-rmse\\\":4.517337363894021}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"K95ot\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 62,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 1,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/K95ot\",\r\n            \"startTime\": 1560835165711,\r\n            \"sequenceId\": 62,\r\n            \"endTime\": 1560835187000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835186487,\r\n                    \"trialJobId\": \"K95ot\",\r\n                    \"parameterId\": \"62\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.529895504017957,\\\"test-rmse\\\":4.853952042009715}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835186487,\r\n                    \"trialJobId\": \"K95ot\",\r\n                    \"parameterId\": \"62\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.529895504017957,\\\"test-rmse\\\":4.853952042009715}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"TYgNw\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 63,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 6,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/TYgNw\",\r\n            \"startTime\": 1560835165750,\r\n            \"sequenceId\": 63,\r\n            \"endTime\": 1560835187000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835186963,\r\n                    \"trialJobId\": \"TYgNw\",\r\n                    \"parameterId\": \"63\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3693117875455716,\\\"test-rmse\\\":4.517337363894021}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835186963,\r\n                    \"trialJobId\": \"TYgNw\",\r\n                    \"parameterId\": \"63\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3693117875455716,\\\"test-rmse\\\":4.517337363894021}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"WzChE\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 64,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 1,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/WzChE\",\r\n            \"startTime\": 1560835180803,\r\n            \"sequenceId\": 64,\r\n            \"endTime\": 1560835197000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835196504,\r\n                    \"trialJobId\": \"WzChE\",\r\n                    \"parameterId\": \"64\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3547341858937134,\\\"test-rmse\\\":4.1572376947288605}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835196504,\r\n                    \"trialJobId\": \"WzChE\",\r\n                    \"parameterId\": \"64\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3547341858937134,\\\"test-rmse\\\":4.1572376947288605}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"iowf5\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 65,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 6,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/iowf5\",\r\n            \"startTime\": 1560835180848,\r\n            \"sequenceId\": 65,\r\n            \"endTime\": 1560835197000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835196577,\r\n                    \"trialJobId\": \"iowf5\",\r\n                    \"parameterId\": \"65\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4155997077622158,\\\"test-rmse\\\":4.5115602918049245}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835196577,\r\n                    \"trialJobId\": \"iowf5\",\r\n                    \"parameterId\": \"65\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4155997077622158,\\\"test-rmse\\\":4.5115602918049245}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"KtfeI\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 66,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 0,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/KtfeI\",\r\n            \"startTime\": 1560835195883,\r\n            \"sequenceId\": 66,\r\n            \"endTime\": 1560835219000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835218367,\r\n                    \"trialJobId\": \"KtfeI\",\r\n                    \"parameterId\": \"66\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6000364121450623,\\\"test-rmse\\\":4.367579676558304}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835218367,\r\n                    \"trialJobId\": \"KtfeI\",\r\n                    \"parameterId\": \"66\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6000364121450623,\\\"test-rmse\\\":4.367579676558304}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"VA73r\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 67,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/VA73r\",\r\n            \"startTime\": 1560835195906,\r\n            \"sequenceId\": 67,\r\n            \"endTime\": 1560835219000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835218855,\r\n                    \"trialJobId\": \"VA73r\",\r\n                    \"parameterId\": \"67\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4802802810775693,\\\"test-rmse\\\":4.767764316499411}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835218855,\r\n                    \"trialJobId\": \"VA73r\",\r\n                    \"parameterId\": \"67\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4802802810775693,\\\"test-rmse\\\":4.767764316499411}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"wxTcu\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 68,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 1,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/wxTcu\",\r\n            \"startTime\": 1560835195930,\r\n            \"sequenceId\": 68,\r\n            \"endTime\": 1560835219000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835218769,\r\n                    \"trialJobId\": \"wxTcu\",\r\n                    \"parameterId\": \"68\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4458378991034095,\\\"test-rmse\\\":4.681977149225176}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835218769,\r\n                    \"trialJobId\": \"wxTcu\",\r\n                    \"parameterId\": \"68\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4458378991034095,\\\"test-rmse\\\":4.681977149225176}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"yKCrx\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 69,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 1,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/yKCrx\",\r\n            \"startTime\": 1560835195956,\r\n            \"sequenceId\": 69,\r\n            \"endTime\": 1560835219000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835218605,\r\n                    \"trialJobId\": \"yKCrx\",\r\n                    \"parameterId\": \"69\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2904924900945116,\\\"test-rmse\\\":4.500605836096965}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835218605,\r\n                    \"trialJobId\": \"yKCrx\",\r\n                    \"parameterId\": \"69\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2904924900945116,\\\"test-rmse\\\":4.500605836096965}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"epR1U\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 70,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 6,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/epR1U\",\r\n            \"startTime\": 1560835195982,\r\n            \"sequenceId\": 70,\r\n            \"endTime\": 1560835219000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835218728,\r\n                    \"trialJobId\": \"epR1U\",\r\n                    \"parameterId\": \"70\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.527740513230204,\\\"test-rmse\\\":4.721609659656817}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835218728,\r\n                    \"trialJobId\": \"epR1U\",\r\n                    \"parameterId\": \"70\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.527740513230204,\\\"test-rmse\\\":4.721609659656817}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"HRBvG\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 71,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 5,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/HRBvG\",\r\n            \"startTime\": 1560835196015,\r\n            \"sequenceId\": 71,\r\n            \"endTime\": 1560835219000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835218883,\r\n                    \"trialJobId\": \"HRBvG\",\r\n                    \"parameterId\": \"71\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6237459794622975,\\\"test-rmse\\\":4.975215737623858}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835218883,\r\n                    \"trialJobId\": \"HRBvG\",\r\n                    \"parameterId\": \"71\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6237459794622975,\\\"test-rmse\\\":4.975215737623858}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"y2oQ7\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 72,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 0,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/y2oQ7\",\r\n            \"startTime\": 1560835206052,\r\n            \"sequenceId\": 72,\r\n            \"endTime\": 1560835225000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835224723,\r\n                    \"trialJobId\": \"y2oQ7\",\r\n                    \"parameterId\": \"72\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.2214648230223615,\\\"test-rmse\\\":6.064063936970124}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835224723,\r\n                    \"trialJobId\": \"y2oQ7\",\r\n                    \"parameterId\": \"72\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.2214648230223615,\\\"test-rmse\\\":6.064063936970124}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"xW78j\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 73,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 4,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/xW78j\",\r\n            \"startTime\": 1560835206092,\r\n            \"sequenceId\": 73,\r\n            \"endTime\": 1560835225000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835224922,\r\n                    \"trialJobId\": \"xW78j\",\r\n                    \"parameterId\": \"73\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.475650619880442,\\\"test-rmse\\\":4.73505926308136}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835224922,\r\n                    \"trialJobId\": \"xW78j\",\r\n                    \"parameterId\": \"73\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.475650619880442,\\\"test-rmse\\\":4.73505926308136}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"xhErq\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 74,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 0,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/xhErq\",\r\n            \"startTime\": 1560835231126,\r\n            \"sequenceId\": 74,\r\n            \"endTime\": 1560835254000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835253789,\r\n                    \"trialJobId\": \"xhErq\",\r\n                    \"parameterId\": \"74\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.088329190578656,\\\"test-rmse\\\":5.813888706137619}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835253789,\r\n                    \"trialJobId\": \"xhErq\",\r\n                    \"parameterId\": \"74\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.088329190578656,\\\"test-rmse\\\":5.813888706137619}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"s6vrc\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 75,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/s6vrc\",\r\n            \"startTime\": 1560835231147,\r\n            \"sequenceId\": 75,\r\n            \"endTime\": 1560835255000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835254713,\r\n                    \"trialJobId\": \"s6vrc\",\r\n                    \"parameterId\": \"75\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3585235890898946,\\\"test-rmse\\\":4.55434130170818}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835254713,\r\n                    \"trialJobId\": \"s6vrc\",\r\n                    \"parameterId\": \"75\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3585235890898946,\\\"test-rmse\\\":4.55434130170818}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"nkji8\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 76,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 4,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/nkji8\",\r\n            \"startTime\": 1560835231167,\r\n            \"sequenceId\": 76,\r\n            \"endTime\": 1560835255000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835254532,\r\n                    \"trialJobId\": \"nkji8\",\r\n                    \"parameterId\": \"76\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2491156358278035,\\\"test-rmse\\\":4.294810041672708}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835254532,\r\n                    \"trialJobId\": \"nkji8\",\r\n                    \"parameterId\": \"76\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2491156358278035,\\\"test-rmse\\\":4.294810041672708}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"gcKoz\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 77,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 3,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/gcKoz\",\r\n            \"startTime\": 1560835231189,\r\n            \"sequenceId\": 77,\r\n            \"endTime\": 1560835255000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835254300,\r\n                    \"trialJobId\": \"gcKoz\",\r\n                    \"parameterId\": \"77\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2569565704776107,\\\"test-rmse\\\":4.348342027108978}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835254300,\r\n                    \"trialJobId\": \"gcKoz\",\r\n                    \"parameterId\": \"77\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2569565704776107,\\\"test-rmse\\\":4.348342027108978}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"zbhiQ\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 78,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 7,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/zbhiQ\",\r\n            \"startTime\": 1560835231212,\r\n            \"sequenceId\": 78,\r\n            \"endTime\": 1560835255000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835254853,\r\n                    \"trialJobId\": \"zbhiQ\",\r\n                    \"parameterId\": \"78\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4412597619617955,\\\"test-rmse\\\":4.636056350363615}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835254853,\r\n                    \"trialJobId\": \"zbhiQ\",\r\n                    \"parameterId\": \"78\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4412597619617955,\\\"test-rmse\\\":4.636056350363615}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"j5zKV\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 79,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 3,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/j5zKV\",\r\n            \"startTime\": 1560835231236,\r\n            \"sequenceId\": 79,\r\n            \"endTime\": 1560835255000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835254566,\r\n                    \"trialJobId\": \"j5zKV\",\r\n                    \"parameterId\": \"79\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2569565704776107,\\\"test-rmse\\\":4.348342027108978}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835254566,\r\n                    \"trialJobId\": \"j5zKV\",\r\n                    \"parameterId\": \"79\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2569565704776107,\\\"test-rmse\\\":4.348342027108978}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"wNcN3\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 80,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 6,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/wNcN3\",\r\n            \"startTime\": 1560835236284,\r\n            \"sequenceId\": 80,\r\n            \"endTime\": 1560835258000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835258436,\r\n                    \"trialJobId\": \"wNcN3\",\r\n                    \"parameterId\": \"80\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.566061649733904,\\\"test-rmse\\\":4.8763800476410335}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835258436,\r\n                    \"trialJobId\": \"wNcN3\",\r\n                    \"parameterId\": \"80\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.566061649733904,\\\"test-rmse\\\":4.8763800476410335}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"fVtec\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 81,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 1,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/fVtec\",\r\n            \"startTime\": 1560835236335,\r\n            \"sequenceId\": 81,\r\n            \"endTime\": 1560835258000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835258231,\r\n                    \"trialJobId\": \"fVtec\",\r\n                    \"parameterId\": \"81\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.115031029439165,\\\"test-rmse\\\":4.05613958752532}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835258231,\r\n                    \"trialJobId\": \"fVtec\",\r\n                    \"parameterId\": \"81\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.115031029439165,\\\"test-rmse\\\":4.05613958752532}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"S4MfR\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 82,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 2,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/S4MfR\",\r\n            \"startTime\": 1560835266374,\r\n            \"sequenceId\": 82,\r\n            \"endTime\": 1560835293000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835292382,\r\n                    \"trialJobId\": \"S4MfR\",\r\n                    \"parameterId\": \"82\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1481138680012184,\\\"test-rmse\\\":4.032017024659914}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835292382,\r\n                    \"trialJobId\": \"S4MfR\",\r\n                    \"parameterId\": \"82\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1481138680012184,\\\"test-rmse\\\":4.032017024659914}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Z6gnz\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 83,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 2,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Z6gnz\",\r\n            \"startTime\": 1560835266395,\r\n            \"sequenceId\": 83,\r\n            \"endTime\": 1560835293000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835292240,\r\n                    \"trialJobId\": \"Z6gnz\",\r\n                    \"parameterId\": \"83\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8321243719053437,\\\"test-rmse\\\":5.4255735575579385}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835292240,\r\n                    \"trialJobId\": \"Z6gnz\",\r\n                    \"parameterId\": \"83\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8321243719053437,\\\"test-rmse\\\":5.4255735575579385}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"E4wCt\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 84,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 5,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/E4wCt\",\r\n            \"startTime\": 1560835266418,\r\n            \"sequenceId\": 84,\r\n            \"endTime\": 1560835293000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835292842,\r\n                    \"trialJobId\": \"E4wCt\",\r\n                    \"parameterId\": \"84\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.236211458500518,\\\"test-rmse\\\":4.241907734197994}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835292842,\r\n                    \"trialJobId\": \"E4wCt\",\r\n                    \"parameterId\": \"84\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.236211458500518,\\\"test-rmse\\\":4.241907734197994}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"ygI7f\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 85,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 5,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/ygI7f\",\r\n            \"startTime\": 1560835266439,\r\n            \"sequenceId\": 85,\r\n            \"endTime\": 1560835293000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835292547,\r\n                    \"trialJobId\": \"ygI7f\",\r\n                    \"parameterId\": \"85\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4670664020829887,\\\"test-rmse\\\":4.698401360258501}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835292547,\r\n                    \"trialJobId\": \"ygI7f\",\r\n                    \"parameterId\": \"85\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4670664020829887,\\\"test-rmse\\\":4.698401360258501}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"QTstb\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 86,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 4,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/QTstb\",\r\n            \"startTime\": 1560835266462,\r\n            \"sequenceId\": 86,\r\n            \"endTime\": 1560835293000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835292665,\r\n                    \"trialJobId\": \"QTstb\",\r\n                    \"parameterId\": \"86\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2407110830715564,\\\"test-rmse\\\":4.200982674640527}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835292665,\r\n                    \"trialJobId\": \"QTstb\",\r\n                    \"parameterId\": \"86\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2407110830715564,\\\"test-rmse\\\":4.200982674640527}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"qf92c\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 87,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 1,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/qf92c\",\r\n            \"startTime\": 1560835266485,\r\n            \"sequenceId\": 87,\r\n            \"endTime\": 1560835293000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835292058,\r\n                    \"trialJobId\": \"qf92c\",\r\n                    \"parameterId\": \"87\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.350790894444206,\\\"test-rmse\\\":4.210514196622158}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835292058,\r\n                    \"trialJobId\": \"qf92c\",\r\n                    \"parameterId\": \"87\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.350790894444206,\\\"test-rmse\\\":4.210514196622158}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"O9JpE\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 88,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 1,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/O9JpE\",\r\n            \"startTime\": 1560835266513,\r\n            \"sequenceId\": 88,\r\n            \"endTime\": 1560835293000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835292500,\r\n                    \"trialJobId\": \"O9JpE\",\r\n                    \"parameterId\": \"88\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.335817674415948,\\\"test-rmse\\\":4.53941202993029}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835292500,\r\n                    \"trialJobId\": \"O9JpE\",\r\n                    \"parameterId\": \"88\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.335817674415948,\\\"test-rmse\\\":4.53941202993029}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"CxUDi\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 89,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 3,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/CxUDi\",\r\n            \"startTime\": 1560835266543,\r\n            \"sequenceId\": 89,\r\n            \"endTime\": 1560835293000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835292462,\r\n                    \"trialJobId\": \"CxUDi\",\r\n                    \"parameterId\": \"89\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8068739925123705,\\\"test-rmse\\\":5.347009006462152}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835292462,\r\n                    \"trialJobId\": \"CxUDi\",\r\n                    \"parameterId\": \"89\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8068739925123705,\\\"test-rmse\\\":5.347009006462152}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"v3rkh\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 90,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 2,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/v3rkh\",\r\n            \"startTime\": 1560835301584,\r\n            \"sequenceId\": 90,\r\n            \"endTime\": 1560835330000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835329305,\r\n                    \"trialJobId\": \"v3rkh\",\r\n                    \"parameterId\": \"90\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.296864053305463,\\\"test-rmse\\\":4.484792307945179}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835329305,\r\n                    \"trialJobId\": \"v3rkh\",\r\n                    \"parameterId\": \"90\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.296864053305463,\\\"test-rmse\\\":4.484792307945179}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"PLHLd\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 91,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 4,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/PLHLd\",\r\n            \"startTime\": 1560835301609,\r\n            \"sequenceId\": 91,\r\n            \"endTime\": 1560835329000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835328954,\r\n                    \"trialJobId\": \"PLHLd\",\r\n                    \"parameterId\": \"91\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7402732919087147,\\\"test-rmse\\\":4.943838899959675}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835328954,\r\n                    \"trialJobId\": \"PLHLd\",\r\n                    \"parameterId\": \"91\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7402732919087147,\\\"test-rmse\\\":4.943838899959675}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"T0S6B\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 92,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 7,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/T0S6B\",\r\n            \"startTime\": 1560835301632,\r\n            \"sequenceId\": 92,\r\n            \"endTime\": 1560835330000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835329464,\r\n                    \"trialJobId\": \"T0S6B\",\r\n                    \"parameterId\": \"92\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6214049787353697,\\\"test-rmse\\\":4.748458253426087}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835329464,\r\n                    \"trialJobId\": \"T0S6B\",\r\n                    \"parameterId\": \"92\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6214049787353697,\\\"test-rmse\\\":4.748458253426087}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"ojk3r\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 93,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 0,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/ojk3r\",\r\n            \"startTime\": 1560835301655,\r\n            \"sequenceId\": 93,\r\n            \"endTime\": 1560835330000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835329377,\r\n                    \"trialJobId\": \"ojk3r\",\r\n                    \"parameterId\": \"93\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2283951751387394,\\\"test-rmse\\\":4.070690391213238}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835329377,\r\n                    \"trialJobId\": \"ojk3r\",\r\n                    \"parameterId\": \"93\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2283951751387394,\\\"test-rmse\\\":4.070690391213238}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"SjFWK\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 94,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 5,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/SjFWK\",\r\n            \"startTime\": 1560835301678,\r\n            \"sequenceId\": 94,\r\n            \"endTime\": 1560835330000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835329765,\r\n                    \"trialJobId\": \"SjFWK\",\r\n                    \"parameterId\": \"94\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2702760709463146,\\\"test-rmse\\\":4.326614997249542}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835329765,\r\n                    \"trialJobId\": \"SjFWK\",\r\n                    \"parameterId\": \"94\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2702760709463146,\\\"test-rmse\\\":4.326614997249542}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"u5PNI\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 95,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 6,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/u5PNI\",\r\n            \"startTime\": 1560835301702,\r\n            \"sequenceId\": 95,\r\n            \"endTime\": 1560835330000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835329515,\r\n                    \"trialJobId\": \"u5PNI\",\r\n                    \"parameterId\": \"95\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7880145879811886,\\\"test-rmse\\\":5.038430193052282}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835329515,\r\n                    \"trialJobId\": \"u5PNI\",\r\n                    \"parameterId\": \"95\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7880145879811886,\\\"test-rmse\\\":5.038430193052282}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"kdjzD\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 96,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 4,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/kdjzD\",\r\n            \"startTime\": 1560835301728,\r\n            \"sequenceId\": 96,\r\n            \"endTime\": 1560835330000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835329555,\r\n                    \"trialJobId\": \"kdjzD\",\r\n                    \"parameterId\": \"96\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7356027543445967,\\\"test-rmse\\\":5.194351021624372}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835329555,\r\n                    \"trialJobId\": \"kdjzD\",\r\n                    \"parameterId\": \"96\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7356027543445967,\\\"test-rmse\\\":5.194351021624372}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"WM0lV\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 97,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 0,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/WM0lV\",\r\n            \"startTime\": 1560835301761,\r\n            \"sequenceId\": 97,\r\n            \"endTime\": 1560835327000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835326709,\r\n                    \"trialJobId\": \"WM0lV\",\r\n                    \"parameterId\": \"97\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.54740553390969,\\\"test-rmse\\\":4.904523342465941}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835326709,\r\n                    \"trialJobId\": \"WM0lV\",\r\n                    \"parameterId\": \"97\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.54740553390969,\\\"test-rmse\\\":4.904523342465941}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"QArDF\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 98,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 2,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/QArDF\",\r\n            \"startTime\": 1560835336801,\r\n            \"sequenceId\": 98,\r\n            \"endTime\": 1560835358000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835357306,\r\n                    \"trialJobId\": \"QArDF\",\r\n                    \"parameterId\": \"98\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.182570017883216,\\\"test-rmse\\\":4.168698760763754}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835357306,\r\n                    \"trialJobId\": \"QArDF\",\r\n                    \"parameterId\": \"98\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.182570017883216,\\\"test-rmse\\\":4.168698760763754}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"REEem\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 99,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 2,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/REEem\",\r\n            \"startTime\": 1560835336824,\r\n            \"sequenceId\": 99,\r\n            \"endTime\": 1560835358000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835357902,\r\n                    \"trialJobId\": \"REEem\",\r\n                    \"parameterId\": \"99\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5144149906355753,\\\"test-rmse\\\":4.80829565743563}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835357902,\r\n                    \"trialJobId\": \"REEem\",\r\n                    \"parameterId\": \"99\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5144149906355753,\\\"test-rmse\\\":4.80829565743563}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"MMksm\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 100,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 5,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/MMksm\",\r\n            \"startTime\": 1560835336844,\r\n            \"sequenceId\": 100,\r\n            \"endTime\": 1560835358000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835357646,\r\n                    \"trialJobId\": \"MMksm\",\r\n                    \"parameterId\": \"100\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2969113404009023,\\\"test-rmse\\\":4.310629315133367}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835357646,\r\n                    \"trialJobId\": \"MMksm\",\r\n                    \"parameterId\": \"100\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2969113404009023,\\\"test-rmse\\\":4.310629315133367}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"idZ8u\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 101,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 1,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/idZ8u\",\r\n            \"startTime\": 1560835336865,\r\n            \"sequenceId\": 101,\r\n            \"endTime\": 1560835358000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835357532,\r\n                    \"trialJobId\": \"idZ8u\",\r\n                    \"parameterId\": \"101\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.852152225593427,\\\"test-rmse\\\":5.457018020376654}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835357532,\r\n                    \"trialJobId\": \"idZ8u\",\r\n                    \"parameterId\": \"101\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.852152225593427,\\\"test-rmse\\\":5.457018020376654}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"W1HFj\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 102,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 7,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/W1HFj\",\r\n            \"startTime\": 1560835341893,\r\n            \"sequenceId\": 102,\r\n            \"endTime\": 1560835362000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835362470,\r\n                    \"trialJobId\": \"W1HFj\",\r\n                    \"parameterId\": \"102\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3715454534088765,\\\"test-rmse\\\":4.510303906855892}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835362470,\r\n                    \"trialJobId\": \"W1HFj\",\r\n                    \"parameterId\": \"102\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3715454534088765,\\\"test-rmse\\\":4.510303906855892}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"lcPwA\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 103,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 6,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/lcPwA\",\r\n            \"startTime\": 1560835341921,\r\n            \"sequenceId\": 103,\r\n            \"endTime\": 1560835362000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835362327,\r\n                    \"trialJobId\": \"lcPwA\",\r\n                    \"parameterId\": \"103\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6753750819649897,\\\"test-rmse\\\":5.075104642124134}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835362327,\r\n                    \"trialJobId\": \"lcPwA\",\r\n                    \"parameterId\": \"103\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6753750819649897,\\\"test-rmse\\\":5.075104642124134}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"f5tl3\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 104,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 0,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/f5tl3\",\r\n            \"startTime\": 1560835341949,\r\n            \"sequenceId\": 104,\r\n            \"endTime\": 1560835362000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835362186,\r\n                    \"trialJobId\": \"f5tl3\",\r\n                    \"parameterId\": \"104\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5191010428127005,\\\"test-rmse\\\":4.81101214229983}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835362186,\r\n                    \"trialJobId\": \"f5tl3\",\r\n                    \"parameterId\": \"104\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5191010428127005,\\\"test-rmse\\\":4.81101214229983}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Rltgw\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 105,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 7,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Rltgw\",\r\n            \"startTime\": 1560835341981,\r\n            \"sequenceId\": 105,\r\n            \"endTime\": 1560835362000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835362351,\r\n                    \"trialJobId\": \"Rltgw\",\r\n                    \"parameterId\": \"105\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3596219353181205,\\\"test-rmse\\\":4.473485451754308}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835362351,\r\n                    \"trialJobId\": \"Rltgw\",\r\n                    \"parameterId\": \"105\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3596219353181205,\\\"test-rmse\\\":4.473485451754308}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"CNNba\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 106,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 1,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/CNNba\",\r\n            \"startTime\": 1560835367022,\r\n            \"sequenceId\": 106,\r\n            \"endTime\": 1560835390000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835389511,\r\n                    \"trialJobId\": \"CNNba\",\r\n                    \"parameterId\": \"106\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.24905460598976,\\\"test-rmse\\\":4.353696152243672}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835389511,\r\n                    \"trialJobId\": \"CNNba\",\r\n                    \"parameterId\": \"106\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.24905460598976,\\\"test-rmse\\\":4.353696152243672}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"epr7s\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 107,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 0,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/epr7s\",\r\n            \"startTime\": 1560835367043,\r\n            \"sequenceId\": 107,\r\n            \"endTime\": 1560835390000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835389258,\r\n                    \"trialJobId\": \"epr7s\",\r\n                    \"parameterId\": \"107\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7879509625021903,\\\"test-rmse\\\":5.324382217774016}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835389258,\r\n                    \"trialJobId\": \"epr7s\",\r\n                    \"parameterId\": \"107\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7879509625021903,\\\"test-rmse\\\":5.324382217774016}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"UrCy5\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 108,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 1,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/UrCy5\",\r\n            \"startTime\": 1560835367065,\r\n            \"sequenceId\": 108,\r\n            \"endTime\": 1560835390000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835389198,\r\n                    \"trialJobId\": \"UrCy5\",\r\n                    \"parameterId\": \"108\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.013539507869146,\\\"test-rmse\\\":5.741185058948712}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835389198,\r\n                    \"trialJobId\": \"UrCy5\",\r\n                    \"parameterId\": \"108\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.013539507869146,\\\"test-rmse\\\":5.741185058948712}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"qQnBq\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 109,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 2,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/qQnBq\",\r\n            \"startTime\": 1560835367088,\r\n            \"sequenceId\": 109,\r\n            \"endTime\": 1560835390000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835389262,\r\n                    \"trialJobId\": \"qQnBq\",\r\n                    \"parameterId\": \"109\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5956408024451454,\\\"test-rmse\\\":5.011881280185782}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835389262,\r\n                    \"trialJobId\": \"qQnBq\",\r\n                    \"parameterId\": \"109\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5956408024451454,\\\"test-rmse\\\":5.011881280185782}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"HbtQF\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 110,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 1,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/HbtQF\",\r\n            \"startTime\": 1560835372112,\r\n            \"sequenceId\": 110,\r\n            \"endTime\": 1560835394000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835393525,\r\n                    \"trialJobId\": \"HbtQF\",\r\n                    \"parameterId\": \"110\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.41869881116218,\\\"test-rmse\\\":4.331528996001897}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835393525,\r\n                    \"trialJobId\": \"HbtQF\",\r\n                    \"parameterId\": \"110\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.41869881116218,\\\"test-rmse\\\":4.331528996001897}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Yu1YW\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 111,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 1,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Yu1YW\",\r\n            \"startTime\": 1560835372138,\r\n            \"sequenceId\": 111,\r\n            \"endTime\": 1560835394000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835393554,\r\n                    \"trialJobId\": \"Yu1YW\",\r\n                    \"parameterId\": \"111\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.013539507869146,\\\"test-rmse\\\":5.741185058948712}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835393554,\r\n                    \"trialJobId\": \"Yu1YW\",\r\n                    \"parameterId\": \"111\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.013539507869146,\\\"test-rmse\\\":5.741185058948712}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"qCfMs\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 112,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 0,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/qCfMs\",\r\n            \"startTime\": 1560835372165,\r\n            \"sequenceId\": 112,\r\n            \"endTime\": 1560835393000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835393472,\r\n                    \"trialJobId\": \"qCfMs\",\r\n                    \"parameterId\": \"112\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.54740553390969,\\\"test-rmse\\\":4.904523342465941}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835393472,\r\n                    \"trialJobId\": \"qCfMs\",\r\n                    \"parameterId\": \"112\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.54740553390969,\\\"test-rmse\\\":4.904523342465941}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"h2u1o\",\r\n            \"status\": \"FAILED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 113,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 0,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/h2u1o\",\r\n            \"startTime\": 1560835372205,\r\n            \"sequenceId\": 113,\r\n            \"endTime\": 1560835393000,\r\n            \"stderrPath\": \"file:/localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/h2u1o/stderr\",\r\n            \"intermediate\": []\r\n        },\r\n        {\r\n            \"id\": \"VBHhs\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 114,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 3,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/VBHhs\",\r\n            \"startTime\": 1560835397238,\r\n            \"sequenceId\": 114,\r\n            \"endTime\": 1560835419000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835418639,\r\n                    \"trialJobId\": \"VBHhs\",\r\n                    \"parameterId\": \"114\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3651437135487714,\\\"test-rmse\\\":4.552893761545617}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835418639,\r\n                    \"trialJobId\": \"VBHhs\",\r\n                    \"parameterId\": \"114\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3651437135487714,\\\"test-rmse\\\":4.552893761545617}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"N232X\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 115,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 2,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/N232X\",\r\n            \"startTime\": 1560835397257,\r\n            \"sequenceId\": 115,\r\n            \"endTime\": 1560835419000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835418412,\r\n                    \"trialJobId\": \"N232X\",\r\n                    \"parameterId\": \"115\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3146710545512597,\\\"test-rmse\\\":4.492402166908771}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835418412,\r\n                    \"trialJobId\": \"N232X\",\r\n                    \"parameterId\": \"115\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3146710545512597,\\\"test-rmse\\\":4.492402166908771}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"mV7mh\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 116,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 5,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/mV7mh\",\r\n            \"startTime\": 1560835397277,\r\n            \"sequenceId\": 116,\r\n            \"endTime\": 1560835419000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835418849,\r\n                    \"trialJobId\": \"mV7mh\",\r\n                    \"parameterId\": \"116\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3802844159832177,\\\"test-rmse\\\":4.5417511282809935}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835418849,\r\n                    \"trialJobId\": \"mV7mh\",\r\n                    \"parameterId\": \"116\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3802844159832177,\\\"test-rmse\\\":4.5417511282809935}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"ywdpv\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 117,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 1,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/ywdpv\",\r\n            \"startTime\": 1560835397296,\r\n            \"sequenceId\": 117,\r\n            \"endTime\": 1560835419000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835418355,\r\n                    \"trialJobId\": \"ywdpv\",\r\n                    \"parameterId\": \"117\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.589004270029374,\\\"test-rmse\\\":5.047706849158978}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835418355,\r\n                    \"trialJobId\": \"ywdpv\",\r\n                    \"parameterId\": \"117\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.589004270029374,\\\"test-rmse\\\":5.047706849158978}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"dRvsN\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 118,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 5,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/dRvsN\",\r\n            \"startTime\": 1560835402326,\r\n            \"sequenceId\": 118,\r\n            \"endTime\": 1560835423000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835423089,\r\n                    \"trialJobId\": \"dRvsN\",\r\n                    \"parameterId\": \"118\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.466012234112674,\\\"test-rmse\\\":4.607805766719761}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835423089,\r\n                    \"trialJobId\": \"dRvsN\",\r\n                    \"parameterId\": \"118\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.466012234112674,\\\"test-rmse\\\":4.607805766719761}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"qFDHo\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 119,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/qFDHo\",\r\n            \"startTime\": 1560835402354,\r\n            \"sequenceId\": 119,\r\n            \"endTime\": 1560835423000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835423209,\r\n                    \"trialJobId\": \"qFDHo\",\r\n                    \"parameterId\": \"119\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.143210529033562,\\\"test-rmse\\\":4.0775311955434965}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835423209,\r\n                    \"trialJobId\": \"qFDHo\",\r\n                    \"parameterId\": \"119\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.143210529033562,\\\"test-rmse\\\":4.0775311955434965}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Ust7J\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 120,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 4,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Ust7J\",\r\n            \"startTime\": 1560835402382,\r\n            \"sequenceId\": 120,\r\n            \"endTime\": 1560835423000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835423394,\r\n                    \"trialJobId\": \"Ust7J\",\r\n                    \"parameterId\": \"120\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7734189500775583,\\\"test-rmse\\\":5.260572896761711}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835423394,\r\n                    \"trialJobId\": \"Ust7J\",\r\n                    \"parameterId\": \"120\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7734189500775583,\\\"test-rmse\\\":5.260572896761711}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"TeIva\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 121,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 0,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/TeIva\",\r\n            \"startTime\": 1560835402416,\r\n            \"sequenceId\": 121,\r\n            \"endTime\": 1560835423000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835423236,\r\n                    \"trialJobId\": \"TeIva\",\r\n                    \"parameterId\": \"121\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8610089017861373,\\\"test-rmse\\\":5.415674405651937}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835423236,\r\n                    \"trialJobId\": \"TeIva\",\r\n                    \"parameterId\": \"121\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8610089017861373,\\\"test-rmse\\\":5.415674405651937}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"o8e81\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 122,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 0,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/o8e81\",\r\n            \"startTime\": 1560835427448,\r\n            \"sequenceId\": 122,\r\n            \"endTime\": 1560835450000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835449522,\r\n                    \"trialJobId\": \"o8e81\",\r\n                    \"parameterId\": \"122\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2556924196526333,\\\"test-rmse\\\":4.039395335209618}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835449522,\r\n                    \"trialJobId\": \"o8e81\",\r\n                    \"parameterId\": \"122\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2556924196526333,\\\"test-rmse\\\":4.039395335209618}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"sfz9K\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 123,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 3,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/sfz9K\",\r\n            \"startTime\": 1560835427470,\r\n            \"sequenceId\": 123,\r\n            \"endTime\": 1560835450000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835449657,\r\n                    \"trialJobId\": \"sfz9K\",\r\n                    \"parameterId\": \"123\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3396245062467016,\\\"test-rmse\\\":4.514011065416418}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835449657,\r\n                    \"trialJobId\": \"sfz9K\",\r\n                    \"parameterId\": \"123\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3396245062467016,\\\"test-rmse\\\":4.514011065416418}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"G68pU\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 124,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 1,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/G68pU\",\r\n            \"startTime\": 1560835427492,\r\n            \"sequenceId\": 124,\r\n            \"endTime\": 1560835450000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835449343,\r\n                    \"trialJobId\": \"G68pU\",\r\n                    \"parameterId\": \"124\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2904924900945116,\\\"test-rmse\\\":4.500605836096965}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835449343,\r\n                    \"trialJobId\": \"G68pU\",\r\n                    \"parameterId\": \"124\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2904924900945116,\\\"test-rmse\\\":4.500605836096965}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"F66fw\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 125,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 2,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/F66fw\",\r\n            \"startTime\": 1560835427513,\r\n            \"sequenceId\": 125,\r\n            \"endTime\": 1560835450000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835449349,\r\n                    \"trialJobId\": \"F66fw\",\r\n                    \"parameterId\": \"125\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.510327263886997,\\\"test-rmse\\\":4.87863065242511}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835449349,\r\n                    \"trialJobId\": \"F66fw\",\r\n                    \"parameterId\": \"125\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.510327263886997,\\\"test-rmse\\\":4.87863065242511}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"WUyLv\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 126,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 3,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/WUyLv\",\r\n            \"startTime\": 1560835432545,\r\n            \"sequenceId\": 126,\r\n            \"endTime\": 1560835454000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835453865,\r\n                    \"trialJobId\": \"WUyLv\",\r\n                    \"parameterId\": \"126\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1917340298568972,\\\"test-rmse\\\":4.122825565650501}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835453865,\r\n                    \"trialJobId\": \"WUyLv\",\r\n                    \"parameterId\": \"126\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1917340298568972,\\\"test-rmse\\\":4.122825565650501}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"uZF0k\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 127,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 6,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/uZF0k\",\r\n            \"startTime\": 1560835432573,\r\n            \"sequenceId\": 127,\r\n            \"endTime\": 1560835454000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835454036,\r\n                    \"trialJobId\": \"uZF0k\",\r\n                    \"parameterId\": \"127\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4830314962014395,\\\"test-rmse\\\":4.72193178462408}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835454036,\r\n                    \"trialJobId\": \"uZF0k\",\r\n                    \"parameterId\": \"127\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4830314962014395,\\\"test-rmse\\\":4.72193178462408}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"gUoJc\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 128,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 7,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/gUoJc\",\r\n            \"startTime\": 1560835432605,\r\n            \"sequenceId\": 128,\r\n            \"endTime\": 1560835454000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835454117,\r\n                    \"trialJobId\": \"gUoJc\",\r\n                    \"parameterId\": \"128\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6488910585025516,\\\"test-rmse\\\":5.023566068285097}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835454117,\r\n                    \"trialJobId\": \"gUoJc\",\r\n                    \"parameterId\": \"128\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6488910585025516,\\\"test-rmse\\\":5.023566068285097}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"gqHPo\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 129,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 4,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/gqHPo\",\r\n            \"startTime\": 1560835432643,\r\n            \"sequenceId\": 129,\r\n            \"endTime\": 1560835454000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835454022,\r\n                    \"trialJobId\": \"gqHPo\",\r\n                    \"parameterId\": \"129\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.341886572777453,\\\"test-rmse\\\":4.399653942828451}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835454022,\r\n                    \"trialJobId\": \"gqHPo\",\r\n                    \"parameterId\": \"129\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.341886572777453,\\\"test-rmse\\\":4.399653942828451}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Vc5vl\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 130,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 2,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Vc5vl\",\r\n            \"startTime\": 1560835457679,\r\n            \"sequenceId\": 130,\r\n            \"endTime\": 1560835480000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835479424,\r\n                    \"trialJobId\": \"Vc5vl\",\r\n                    \"parameterId\": \"130\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3340172004762385,\\\"test-rmse\\\":4.202920371915793}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835479424,\r\n                    \"trialJobId\": \"Vc5vl\",\r\n                    \"parameterId\": \"130\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3340172004762385,\\\"test-rmse\\\":4.202920371915793}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"qGUuI\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 131,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 5,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/qGUuI\",\r\n            \"startTime\": 1560835457702,\r\n            \"sequenceId\": 131,\r\n            \"endTime\": 1560835480000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835479287,\r\n                    \"trialJobId\": \"qGUuI\",\r\n                    \"parameterId\": \"131\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.623198507978478,\\\"test-rmse\\\":4.884359251025431}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835479287,\r\n                    \"trialJobId\": \"qGUuI\",\r\n                    \"parameterId\": \"131\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.623198507978478,\\\"test-rmse\\\":4.884359251025431}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"wtJaA\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 132,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 4,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/wtJaA\",\r\n            \"startTime\": 1560835457723,\r\n            \"sequenceId\": 132,\r\n            \"endTime\": 1560835480000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835479386,\r\n                    \"trialJobId\": \"wtJaA\",\r\n                    \"parameterId\": \"132\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.574900125022989,\\\"test-rmse\\\":4.8898966546149625}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835479386,\r\n                    \"trialJobId\": \"wtJaA\",\r\n                    \"parameterId\": \"132\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.574900125022989,\\\"test-rmse\\\":4.8898966546149625}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"M72MI\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 133,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 1,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/M72MI\",\r\n            \"startTime\": 1560835457745,\r\n            \"sequenceId\": 133,\r\n            \"endTime\": 1560835479000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835479187,\r\n                    \"trialJobId\": \"M72MI\",\r\n                    \"parameterId\": \"133\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.161037726153426,\\\"test-rmse\\\":5.985420766428313}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835479187,\r\n                    \"trialJobId\": \"M72MI\",\r\n                    \"parameterId\": \"133\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.161037726153426,\\\"test-rmse\\\":5.985420766428313}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"EgNck\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 134,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 2,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/EgNck\",\r\n            \"startTime\": 1560835462777,\r\n            \"sequenceId\": 134,\r\n            \"endTime\": 1560835484000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835483642,\r\n                    \"trialJobId\": \"EgNck\",\r\n                    \"parameterId\": \"134\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2679195534286474,\\\"test-rmse\\\":4.363781360262389}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835483642,\r\n                    \"trialJobId\": \"EgNck\",\r\n                    \"parameterId\": \"134\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2679195534286474,\\\"test-rmse\\\":4.363781360262389}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"RGwWK\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 135,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 5,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/RGwWK\",\r\n            \"startTime\": 1560835462803,\r\n            \"sequenceId\": 135,\r\n            \"endTime\": 1560835484000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835483916,\r\n                    \"trialJobId\": \"RGwWK\",\r\n                    \"parameterId\": \"135\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.466012234112674,\\\"test-rmse\\\":4.607805766719761}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835483916,\r\n                    \"trialJobId\": \"RGwWK\",\r\n                    \"parameterId\": \"135\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.466012234112674,\\\"test-rmse\\\":4.607805766719761}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"EJAWR\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 136,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 2,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/EJAWR\",\r\n            \"startTime\": 1560835462831,\r\n            \"sequenceId\": 136,\r\n            \"endTime\": 1560835484000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835484022,\r\n                    \"trialJobId\": \"EJAWR\",\r\n                    \"parameterId\": \"136\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.302681501844265,\\\"test-rmse\\\":4.429042912188717}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835484022,\r\n                    \"trialJobId\": \"EJAWR\",\r\n                    \"parameterId\": \"136\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.302681501844265,\\\"test-rmse\\\":4.429042912188717}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"ZRTLo\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 137,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 4,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/ZRTLo\",\r\n            \"startTime\": 1560835462865,\r\n            \"sequenceId\": 137,\r\n            \"endTime\": 1560835484000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835483927,\r\n                    \"trialJobId\": \"ZRTLo\",\r\n                    \"parameterId\": \"137\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.341886572777453,\\\"test-rmse\\\":4.399653942828451}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835483927,\r\n                    \"trialJobId\": \"ZRTLo\",\r\n                    \"parameterId\": \"137\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.341886572777453,\\\"test-rmse\\\":4.399653942828451}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"PRguq\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 138,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 3,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/PRguq\",\r\n            \"startTime\": 1560835487902,\r\n            \"sequenceId\": 138,\r\n            \"endTime\": 1560835509000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835509167,\r\n                    \"trialJobId\": \"PRguq\",\r\n                    \"parameterId\": \"138\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.373656593902777,\\\"test-rmse\\\":4.510514323291564}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835509167,\r\n                    \"trialJobId\": \"PRguq\",\r\n                    \"parameterId\": \"138\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.373656593902777,\\\"test-rmse\\\":4.510514323291564}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"fENUc\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 139,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 1,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/fENUc\",\r\n            \"startTime\": 1560835487923,\r\n            \"sequenceId\": 139,\r\n            \"endTime\": 1560835509000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835509152,\r\n                    \"trialJobId\": \"fENUc\",\r\n                    \"parameterId\": \"139\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.17493346457587,\\\"test-rmse\\\":4.2415025747379325}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835509152,\r\n                    \"trialJobId\": \"fENUc\",\r\n                    \"parameterId\": \"139\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.17493346457587,\\\"test-rmse\\\":4.2415025747379325}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"EJ4k8\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 140,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 1,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/EJ4k8\",\r\n            \"startTime\": 1560835487943,\r\n            \"sequenceId\": 140,\r\n            \"endTime\": 1560835510000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835509329,\r\n                    \"trialJobId\": \"EJ4k8\",\r\n                    \"parameterId\": \"140\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7930121602555977,\\\"test-rmse\\\":5.327490807387864}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835509329,\r\n                    \"trialJobId\": \"EJ4k8\",\r\n                    \"parameterId\": \"140\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7930121602555977,\\\"test-rmse\\\":5.327490807387864}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"AuR15\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 141,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 3,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/AuR15\",\r\n            \"startTime\": 1560835487966,\r\n            \"sequenceId\": 141,\r\n            \"endTime\": 1560835510000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835509340,\r\n                    \"trialJobId\": \"AuR15\",\r\n                    \"parameterId\": \"141\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3396245062467016,\\\"test-rmse\\\":4.514011065416418}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835509340,\r\n                    \"trialJobId\": \"AuR15\",\r\n                    \"parameterId\": \"141\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3396245062467016,\\\"test-rmse\\\":4.514011065416418}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"PUutZ\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 142,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 4,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/PUutZ\",\r\n            \"startTime\": 1560835492994,\r\n            \"sequenceId\": 142,\r\n            \"endTime\": 1560835514000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835513916,\r\n                    \"trialJobId\": \"PUutZ\",\r\n                    \"parameterId\": \"142\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.217457077626387,\\\"test-rmse\\\":4.217031486564704}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835513916,\r\n                    \"trialJobId\": \"PUutZ\",\r\n                    \"parameterId\": \"142\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.217457077626387,\\\"test-rmse\\\":4.217031486564704}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"aloQc\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 143,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 2,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/aloQc\",\r\n            \"startTime\": 1560835493021,\r\n            \"sequenceId\": 143,\r\n            \"endTime\": 1560835514000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835513946,\r\n                    \"trialJobId\": \"aloQc\",\r\n                    \"parameterId\": \"143\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4093262849184933,\\\"test-rmse\\\":4.622618621755476}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835513946,\r\n                    \"trialJobId\": \"aloQc\",\r\n                    \"parameterId\": \"143\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4093262849184933,\\\"test-rmse\\\":4.622618621755476}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Cz4p2\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 144,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 5,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Cz4p2\",\r\n            \"startTime\": 1560835493051,\r\n            \"sequenceId\": 144,\r\n            \"endTime\": 1560835514000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835513896,\r\n                    \"trialJobId\": \"Cz4p2\",\r\n                    \"parameterId\": \"144\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6368827003389894,\\\"test-rmse\\\":5.007860355640729}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835513896,\r\n                    \"trialJobId\": \"Cz4p2\",\r\n                    \"parameterId\": \"144\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6368827003389894,\\\"test-rmse\\\":5.007860355640729}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"jk8L0\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 145,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 1,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/jk8L0\",\r\n            \"startTime\": 1560835493082,\r\n            \"sequenceId\": 145,\r\n            \"endTime\": 1560835514000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835513614,\r\n                    \"trialJobId\": \"jk8L0\",\r\n                    \"parameterId\": \"145\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.013539507869146,\\\"test-rmse\\\":5.741185058948712}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835513614,\r\n                    \"trialJobId\": \"jk8L0\",\r\n                    \"parameterId\": \"145\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.013539507869146,\\\"test-rmse\\\":5.741185058948712}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"WXELh\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 146,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 4,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/WXELh\",\r\n            \"startTime\": 1560835518123,\r\n            \"sequenceId\": 146,\r\n            \"endTime\": 1560835540000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835539855,\r\n                    \"trialJobId\": \"WXELh\",\r\n                    \"parameterId\": \"146\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.572369188547026,\\\"test-rmse\\\":4.910039558096488}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835539855,\r\n                    \"trialJobId\": \"WXELh\",\r\n                    \"parameterId\": \"146\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.572369188547026,\\\"test-rmse\\\":4.910039558096488}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"rGfPz\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 147,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 4,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/rGfPz\",\r\n            \"startTime\": 1560835518144,\r\n            \"sequenceId\": 147,\r\n            \"endTime\": 1560835540000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835539471,\r\n                    \"trialJobId\": \"rGfPz\",\r\n                    \"parameterId\": \"147\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.636795652088819,\\\"test-rmse\\\":5.018191803532271}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835539471,\r\n                    \"trialJobId\": \"rGfPz\",\r\n                    \"parameterId\": \"147\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.636795652088819,\\\"test-rmse\\\":5.018191803532271}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"H1AJG\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 148,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 0,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/H1AJG\",\r\n            \"startTime\": 1560835518164,\r\n            \"sequenceId\": 148,\r\n            \"endTime\": 1560835540000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835539428,\r\n                    \"trialJobId\": \"H1AJG\",\r\n                    \"parameterId\": \"148\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.983152318549727,\\\"test-rmse\\\":5.6545755866827845}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835539428,\r\n                    \"trialJobId\": \"H1AJG\",\r\n                    \"parameterId\": \"148\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.983152318549727,\\\"test-rmse\\\":5.6545755866827845}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"gu8pK\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 149,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 5,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/gu8pK\",\r\n            \"startTime\": 1560835518185,\r\n            \"sequenceId\": 149,\r\n            \"endTime\": 1560835540000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835539996,\r\n                    \"trialJobId\": \"gu8pK\",\r\n                    \"parameterId\": \"149\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6368827003389894,\\\"test-rmse\\\":5.007860355640729}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835539996,\r\n                    \"trialJobId\": \"gu8pK\",\r\n                    \"parameterId\": \"149\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6368827003389894,\\\"test-rmse\\\":5.007860355640729}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"pEOY4\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 150,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 1,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/pEOY4\",\r\n            \"startTime\": 1560835523214,\r\n            \"sequenceId\": 150,\r\n            \"endTime\": 1560835544000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835544138,\r\n                    \"trialJobId\": \"pEOY4\",\r\n                    \"parameterId\": \"150\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1055594221608507,\\\"test-rmse\\\":3.992244632923753}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835544138,\r\n                    \"trialJobId\": \"pEOY4\",\r\n                    \"parameterId\": \"150\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1055594221608507,\\\"test-rmse\\\":3.992244632923753}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"jjcZW\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 151,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 6,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/jjcZW\",\r\n            \"startTime\": 1560835523244,\r\n            \"sequenceId\": 151,\r\n            \"endTime\": 1560835544000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835544219,\r\n                    \"trialJobId\": \"jjcZW\",\r\n                    \"parameterId\": \"151\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.374924096159413,\\\"test-rmse\\\":4.499867384060287}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835544219,\r\n                    \"trialJobId\": \"jjcZW\",\r\n                    \"parameterId\": \"151\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.374924096159413,\\\"test-rmse\\\":4.499867384060287}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"jhQFn\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 152,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 5,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/jhQFn\",\r\n            \"startTime\": 1560835523270,\r\n            \"sequenceId\": 152,\r\n            \"endTime\": 1560835544000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835544142,\r\n                    \"trialJobId\": \"jhQFn\",\r\n                    \"parameterId\": \"152\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4208039705028863,\\\"test-rmse\\\":4.592784722139947}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835544142,\r\n                    \"trialJobId\": \"jhQFn\",\r\n                    \"parameterId\": \"152\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4208039705028863,\\\"test-rmse\\\":4.592784722139947}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"SDr55\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 153,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 1,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/SDr55\",\r\n            \"startTime\": 1560835523305,\r\n            \"sequenceId\": 153,\r\n            \"endTime\": 1560835544000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835544211,\r\n                    \"trialJobId\": \"SDr55\",\r\n                    \"parameterId\": \"153\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.17493346457587,\\\"test-rmse\\\":4.2415025747379325}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835544211,\r\n                    \"trialJobId\": \"SDr55\",\r\n                    \"parameterId\": \"153\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.17493346457587,\\\"test-rmse\\\":4.2415025747379325}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"DSKTs\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 154,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/DSKTs\",\r\n            \"startTime\": 1560835548341,\r\n            \"sequenceId\": 154,\r\n            \"endTime\": 1560835570000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835569629,\r\n                    \"trialJobId\": \"DSKTs\",\r\n                    \"parameterId\": \"154\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3547013756521435,\\\"test-rmse\\\":4.283603601108812}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835569629,\r\n                    \"trialJobId\": \"DSKTs\",\r\n                    \"parameterId\": \"154\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3547013756521435,\\\"test-rmse\\\":4.283603601108812}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"HcPyD\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 155,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/HcPyD\",\r\n            \"startTime\": 1560835548364,\r\n            \"sequenceId\": 155,\r\n            \"endTime\": 1560835570000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835570009,\r\n                    \"trialJobId\": \"HcPyD\",\r\n                    \"parameterId\": \"155\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4802802810775693,\\\"test-rmse\\\":4.767764316499411}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835570009,\r\n                    \"trialJobId\": \"HcPyD\",\r\n                    \"parameterId\": \"155\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4802802810775693,\\\"test-rmse\\\":4.767764316499411}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"I6BTI\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 156,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 0,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/I6BTI\",\r\n            \"startTime\": 1560835548385,\r\n            \"sequenceId\": 156,\r\n            \"endTime\": 1560835570000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835569703,\r\n                    \"trialJobId\": \"I6BTI\",\r\n                    \"parameterId\": \"156\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5191010428127005,\\\"test-rmse\\\":4.81101214229983}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835569703,\r\n                    \"trialJobId\": \"I6BTI\",\r\n                    \"parameterId\": \"156\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5191010428127005,\\\"test-rmse\\\":4.81101214229983}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"IY866\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 157,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 0,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/IY866\",\r\n            \"startTime\": 1560835548413,\r\n            \"sequenceId\": 157,\r\n            \"endTime\": 1560835570000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835569663,\r\n                    \"trialJobId\": \"IY866\",\r\n                    \"parameterId\": \"157\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.538208791457419,\\\"test-rmse\\\":4.822044041480414}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835569663,\r\n                    \"trialJobId\": \"IY866\",\r\n                    \"parameterId\": \"157\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.538208791457419,\\\"test-rmse\\\":4.822044041480414}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"WoaTv\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 158,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 5,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/WoaTv\",\r\n            \"startTime\": 1560835553436,\r\n            \"sequenceId\": 158,\r\n            \"endTime\": 1560835574000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835574253,\r\n                    \"trialJobId\": \"WoaTv\",\r\n                    \"parameterId\": \"158\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5376025649718303,\\\"test-rmse\\\":4.8234107082146}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835574253,\r\n                    \"trialJobId\": \"WoaTv\",\r\n                    \"parameterId\": \"158\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5376025649718303,\\\"test-rmse\\\":4.8234107082146}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"dZXfh\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 159,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 3,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/dZXfh\",\r\n            \"startTime\": 1560835553462,\r\n            \"sequenceId\": 159,\r\n            \"endTime\": 1560835574000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835574120,\r\n                    \"trialJobId\": \"dZXfh\",\r\n                    \"parameterId\": \"159\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.470708675501815,\\\"test-rmse\\\":4.738248229225812}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835574120,\r\n                    \"trialJobId\": \"dZXfh\",\r\n                    \"parameterId\": \"159\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.470708675501815,\\\"test-rmse\\\":4.738248229225812}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Wjvkn\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 160,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 6,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Wjvkn\",\r\n            \"startTime\": 1560835553489,\r\n            \"sequenceId\": 160,\r\n            \"endTime\": 1560835574000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835574229,\r\n                    \"trialJobId\": \"Wjvkn\",\r\n                    \"parameterId\": \"160\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2749368288289036,\\\"test-rmse\\\":4.272061981362897}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835574229,\r\n                    \"trialJobId\": \"Wjvkn\",\r\n                    \"parameterId\": \"160\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2749368288289036,\\\"test-rmse\\\":4.272061981362897}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"LyTEp\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 161,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 5,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/LyTEp\",\r\n            \"startTime\": 1560835553520,\r\n            \"sequenceId\": 161,\r\n            \"endTime\": 1560835574000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835574376,\r\n                    \"trialJobId\": \"LyTEp\",\r\n                    \"parameterId\": \"161\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.543106289211979,\\\"test-rmse\\\":4.831117689442712}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835574376,\r\n                    \"trialJobId\": \"LyTEp\",\r\n                    \"parameterId\": \"161\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.543106289211979,\\\"test-rmse\\\":4.831117689442712}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"sHt3c\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 162,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 1,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/sHt3c\",\r\n            \"startTime\": 1560835583565,\r\n            \"sequenceId\": 162,\r\n            \"endTime\": 1560835605000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835604771,\r\n                    \"trialJobId\": \"sHt3c\",\r\n                    \"parameterId\": \"162\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.174530800023379,\\\"test-rmse\\\":4.231832613503912}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835604771,\r\n                    \"trialJobId\": \"sHt3c\",\r\n                    \"parameterId\": \"162\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.174530800023379,\\\"test-rmse\\\":4.231832613503912}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"N6jtc\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 163,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 5,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/N6jtc\",\r\n            \"startTime\": 1560835583587,\r\n            \"sequenceId\": 163,\r\n            \"endTime\": 1560835605000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835605057,\r\n                    \"trialJobId\": \"N6jtc\",\r\n                    \"parameterId\": \"163\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6002175910095007,\\\"test-rmse\\\":4.9367966115751365}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835605057,\r\n                    \"trialJobId\": \"N6jtc\",\r\n                    \"parameterId\": \"163\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.6002175910095007,\\\"test-rmse\\\":4.9367966115751365}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"GFm4U\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 164,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 6,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/GFm4U\",\r\n            \"startTime\": 1560835583609,\r\n            \"sequenceId\": 164,\r\n            \"endTime\": 1560835605000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835605159,\r\n                    \"trialJobId\": \"GFm4U\",\r\n                    \"parameterId\": \"164\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3343664050554174,\\\"test-rmse\\\":4.36618297262181}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835605159,\r\n                    \"trialJobId\": \"GFm4U\",\r\n                    \"parameterId\": \"164\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3343664050554174,\\\"test-rmse\\\":4.36618297262181}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"RVTpK\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 165,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 2,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/RVTpK\",\r\n            \"startTime\": 1560835583630,\r\n            \"sequenceId\": 165,\r\n            \"endTime\": 1560835605000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835605095,\r\n                    \"trialJobId\": \"RVTpK\",\r\n                    \"parameterId\": \"165\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1481138680012184,\\\"test-rmse\\\":4.032017024659914}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835605095,\r\n                    \"trialJobId\": \"RVTpK\",\r\n                    \"parameterId\": \"165\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1481138680012184,\\\"test-rmse\\\":4.032017024659914}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"PE3y9\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 166,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 2,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/PE3y9\",\r\n            \"startTime\": 1560835588658,\r\n            \"sequenceId\": 166,\r\n            \"endTime\": 1560835610000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835609340,\r\n                    \"trialJobId\": \"PE3y9\",\r\n                    \"parameterId\": \"166\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8321243719053437,\\\"test-rmse\\\":5.4255735575579385}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835609340,\r\n                    \"trialJobId\": \"PE3y9\",\r\n                    \"parameterId\": \"166\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.8321243719053437,\\\"test-rmse\\\":5.4255735575579385}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"yiSse\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 167,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 0,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/yiSse\",\r\n            \"startTime\": 1560835588684,\r\n            \"sequenceId\": 167,\r\n            \"endTime\": 1560835610000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835609331,\r\n                    \"trialJobId\": \"yiSse\",\r\n                    \"parameterId\": \"167\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.5027885409903,\\\"test-rmse\\\":6.523386902721849}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835609331,\r\n                    \"trialJobId\": \"yiSse\",\r\n                    \"parameterId\": \"167\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.5027885409903,\\\"test-rmse\\\":6.523386902721849}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"sYnuS\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 168,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 3,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/sYnuS\",\r\n            \"startTime\": 1560835588715,\r\n            \"sequenceId\": 168,\r\n            \"endTime\": 1560835610000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835609473,\r\n                    \"trialJobId\": \"sYnuS\",\r\n                    \"parameterId\": \"168\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2569565704776107,\\\"test-rmse\\\":4.348342027108978}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835609473,\r\n                    \"trialJobId\": \"sYnuS\",\r\n                    \"parameterId\": \"168\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2569565704776107,\\\"test-rmse\\\":4.348342027108978}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"ZWiQL\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 169,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 7,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/ZWiQL\",\r\n            \"startTime\": 1560835588776,\r\n            \"sequenceId\": 169,\r\n            \"endTime\": 1560835610000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835609795,\r\n                    \"trialJobId\": \"ZWiQL\",\r\n                    \"parameterId\": \"169\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3573408463670296,\\\"test-rmse\\\":4.4766049838814865}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835609795,\r\n                    \"trialJobId\": \"ZWiQL\",\r\n                    \"parameterId\": \"169\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3573408463670296,\\\"test-rmse\\\":4.4766049838814865}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"eqLXi\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 170,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 3,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/eqLXi\",\r\n            \"startTime\": 1560835618824,\r\n            \"sequenceId\": 170,\r\n            \"endTime\": 1560835641000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835640884,\r\n                    \"trialJobId\": \"eqLXi\",\r\n                    \"parameterId\": \"170\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7661661190160194,\\\"test-rmse\\\":5.284076256072274}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835640884,\r\n                    \"trialJobId\": \"eqLXi\",\r\n                    \"parameterId\": \"170\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.7661661190160194,\\\"test-rmse\\\":5.284076256072274}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"ER87A\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 171,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 3,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/ER87A\",\r\n            \"startTime\": 1560835618846,\r\n            \"sequenceId\": 171,\r\n            \"endTime\": 1560835641000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835640971,\r\n                    \"trialJobId\": \"ER87A\",\r\n                    \"parameterId\": \"171\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1917340298568972,\\\"test-rmse\\\":4.122825565650501}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835640971,\r\n                    \"trialJobId\": \"ER87A\",\r\n                    \"parameterId\": \"171\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1917340298568972,\\\"test-rmse\\\":4.122825565650501}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"fJpco\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 172,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 6,\r\n                    \"PT\": 2,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/fJpco\",\r\n            \"startTime\": 1560835618865,\r\n            \"sequenceId\": 172,\r\n            \"endTime\": 1560835641000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835641100,\r\n                    \"trialJobId\": \"fJpco\",\r\n                    \"parameterId\": \"172\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5144149906355753,\\\"test-rmse\\\":4.80829565743563}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835641100,\r\n                    \"trialJobId\": \"fJpco\",\r\n                    \"parameterId\": \"172\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.5144149906355753,\\\"test-rmse\\\":4.80829565743563}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"fq2Wz\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 173,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 5,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/fq2Wz\",\r\n            \"startTime\": 1560835618885,\r\n            \"sequenceId\": 173,\r\n            \"endTime\": 1560835641000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835641037,\r\n                    \"trialJobId\": \"fq2Wz\",\r\n                    \"parameterId\": \"173\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3327602079012486,\\\"test-rmse\\\":4.426108555884569}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835641037,\r\n                    \"trialJobId\": \"fq2Wz\",\r\n                    \"parameterId\": \"173\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3327602079012486,\\\"test-rmse\\\":4.426108555884569}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"iz08s\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 174,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 0,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/iz08s\",\r\n            \"startTime\": 1560835623916,\r\n            \"sequenceId\": 174,\r\n            \"endTime\": 1560835645000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835644972,\r\n                    \"trialJobId\": \"iz08s\",\r\n                    \"parameterId\": \"174\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3827099800853486,\\\"test-rmse\\\":4.53019615198143}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835644972,\r\n                    \"trialJobId\": \"iz08s\",\r\n                    \"parameterId\": \"174\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3827099800853486,\\\"test-rmse\\\":4.53019615198143}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"xzLCp\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 175,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 2,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/xzLCp\",\r\n            \"startTime\": 1560835623942,\r\n            \"sequenceId\": 175,\r\n            \"endTime\": 1560835645000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835644971,\r\n                    \"trialJobId\": \"xzLCp\",\r\n                    \"parameterId\": \"175\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.452758148947186,\\\"test-rmse\\\":4.73664073753838}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835644971,\r\n                    \"trialJobId\": \"xzLCp\",\r\n                    \"parameterId\": \"175\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.452758148947186,\\\"test-rmse\\\":4.73664073753838}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"CA3cY\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 176,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 4,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/CA3cY\",\r\n            \"startTime\": 1560835623972,\r\n            \"sequenceId\": 176,\r\n            \"endTime\": 1560835645000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835645046,\r\n                    \"trialJobId\": \"CA3cY\",\r\n                    \"parameterId\": \"176\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3731091235682302,\\\"test-rmse\\\":4.539724457259303}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835645046,\r\n                    \"trialJobId\": \"CA3cY\",\r\n                    \"parameterId\": \"176\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3731091235682302,\\\"test-rmse\\\":4.539724457259303}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"pc3KY\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 177,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 7,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/pc3KY\",\r\n            \"startTime\": 1560835624015,\r\n            \"sequenceId\": 177,\r\n            \"endTime\": 1560835645000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835645193,\r\n                    \"trialJobId\": \"pc3KY\",\r\n                    \"parameterId\": \"177\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3573408463670296,\\\"test-rmse\\\":4.4766049838814865}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835645193,\r\n                    \"trialJobId\": \"pc3KY\",\r\n                    \"parameterId\": \"177\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3573408463670296,\\\"test-rmse\\\":4.4766049838814865}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"NweWw\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 178,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/NweWw\",\r\n            \"startTime\": 1560835654054,\r\n            \"sequenceId\": 178,\r\n            \"endTime\": 1560835680000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835679941,\r\n                    \"trialJobId\": \"NweWw\",\r\n                    \"parameterId\": \"178\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1470693792784425,\\\"test-rmse\\\":4.1530017210869605}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835679941,\r\n                    \"trialJobId\": \"NweWw\",\r\n                    \"parameterId\": \"178\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1470693792784425,\\\"test-rmse\\\":4.1530017210869605}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"dxdsZ\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 179,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 6,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/dxdsZ\",\r\n            \"startTime\": 1560835654079,\r\n            \"sequenceId\": 179,\r\n            \"endTime\": 1560835681000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835680448,\r\n                    \"trialJobId\": \"dxdsZ\",\r\n                    \"parameterId\": \"179\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.218453284374901,\\\"test-rmse\\\":4.212365638586098}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835680448,\r\n                    \"trialJobId\": \"dxdsZ\",\r\n                    \"parameterId\": \"179\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.218453284374901,\\\"test-rmse\\\":4.212365638586098}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"kVMcD\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 180,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 3,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/kVMcD\",\r\n            \"startTime\": 1560835654100,\r\n            \"sequenceId\": 180,\r\n            \"endTime\": 1560835681000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835680256,\r\n                    \"trialJobId\": \"kVMcD\",\r\n                    \"parameterId\": \"180\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4508403190092913,\\\"test-rmse\\\":4.713539586625204}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835680256,\r\n                    \"trialJobId\": \"kVMcD\",\r\n                    \"parameterId\": \"180\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4508403190092913,\\\"test-rmse\\\":4.713539586625204}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Q3RCS\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 181,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 5,\r\n                    \"TT\": 0\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Q3RCS\",\r\n            \"startTime\": 1560835654122,\r\n            \"sequenceId\": 181,\r\n            \"endTime\": 1560835681000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835680153,\r\n                    \"trialJobId\": \"Q3RCS\",\r\n                    \"parameterId\": \"181\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.682732445987853,\\\"test-rmse\\\":5.0880574477617}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835680153,\r\n                    \"trialJobId\": \"Q3RCS\",\r\n                    \"parameterId\": \"181\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.682732445987853,\\\"test-rmse\\\":5.0880574477617}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"W77fA\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 182,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 3,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/W77fA\",\r\n            \"startTime\": 1560835659156,\r\n            \"sequenceId\": 182,\r\n            \"endTime\": 1560835684000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835684443,\r\n                    \"trialJobId\": \"W77fA\",\r\n                    \"parameterId\": \"182\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.573628722958788,\\\"test-rmse\\\":4.947417906356731}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835684443,\r\n                    \"trialJobId\": \"W77fA\",\r\n                    \"parameterId\": \"182\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.573628722958788,\\\"test-rmse\\\":4.947417906356731}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"Wq9HF\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 183,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 0,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/Wq9HF\",\r\n            \"startTime\": 1560835659195,\r\n            \"sequenceId\": 183,\r\n            \"endTime\": 1560835684000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835684306,\r\n                    \"trialJobId\": \"Wq9HF\",\r\n                    \"parameterId\": \"183\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2283951751387394,\\\"test-rmse\\\":4.070690391213238}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835684306,\r\n                    \"trialJobId\": \"Wq9HF\",\r\n                    \"parameterId\": \"183\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2283951751387394,\\\"test-rmse\\\":4.070690391213238}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"EwQNS\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 184,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 0,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/EwQNS\",\r\n            \"startTime\": 1560835659248,\r\n            \"sequenceId\": 184,\r\n            \"endTime\": 1560835684000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835684364,\r\n                    \"trialJobId\": \"EwQNS\",\r\n                    \"parameterId\": \"184\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2283951751387394,\\\"test-rmse\\\":4.070690391213238}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835684364,\r\n                    \"trialJobId\": \"EwQNS\",\r\n                    \"parameterId\": \"184\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2283951751387394,\\\"test-rmse\\\":4.070690391213238}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"THi8X\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 185,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 4,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/THi8X\",\r\n            \"startTime\": 1560835659297,\r\n            \"sequenceId\": 185,\r\n            \"endTime\": 1560835685000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835684636,\r\n                    \"trialJobId\": \"THi8X\",\r\n                    \"parameterId\": \"185\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3831994004985777,\\\"test-rmse\\\":4.560112758181482}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835684636,\r\n                    \"trialJobId\": \"THi8X\",\r\n                    \"parameterId\": \"185\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3831994004985777,\\\"test-rmse\\\":4.560112758181482}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"m6bmt\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 186,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 1,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/m6bmt\",\r\n            \"startTime\": 1560835694336,\r\n            \"sequenceId\": 186,\r\n            \"endTime\": 1560835721000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835720973,\r\n                    \"trialJobId\": \"m6bmt\",\r\n                    \"parameterId\": \"186\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1356318325357733,\\\"test-rmse\\\":3.9711626205809805}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835720973,\r\n                    \"trialJobId\": \"m6bmt\",\r\n                    \"parameterId\": \"186\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.1356318325357733,\\\"test-rmse\\\":3.9711626205809805}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"CBixb\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 187,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 4,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/CBixb\",\r\n            \"startTime\": 1560835694357,\r\n            \"sequenceId\": 187,\r\n            \"endTime\": 1560835722000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835721528,\r\n                    \"trialJobId\": \"CBixb\",\r\n                    \"parameterId\": \"187\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.560701035842575,\\\"test-rmse\\\":4.8776800312862045}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835721528,\r\n                    \"trialJobId\": \"CBixb\",\r\n                    \"parameterId\": \"187\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.560701035842575,\\\"test-rmse\\\":4.8776800312862045}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"pp84V\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 188,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 4,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/pp84V\",\r\n            \"startTime\": 1560835694378,\r\n            \"sequenceId\": 188,\r\n            \"endTime\": 1560835722000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835721451,\r\n                    \"trialJobId\": \"pp84V\",\r\n                    \"parameterId\": \"188\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.217457077626387,\\\"test-rmse\\\":4.217031486564704}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835721451,\r\n                    \"trialJobId\": \"pp84V\",\r\n                    \"parameterId\": \"188\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.217457077626387,\\\"test-rmse\\\":4.217031486564704}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"mvSvX\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 189,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 3,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/mvSvX\",\r\n            \"startTime\": 1560835694401,\r\n            \"sequenceId\": 189,\r\n            \"endTime\": 1560835722000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835721342,\r\n                    \"trialJobId\": \"mvSvX\",\r\n                    \"parameterId\": \"189\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.405985043077917,\\\"test-rmse\\\":4.609202426525674}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835721342,\r\n                    \"trialJobId\": \"mvSvX\",\r\n                    \"parameterId\": \"189\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.405985043077917,\\\"test-rmse\\\":4.609202426525674}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"wcNTX\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 190,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/wcNTX\",\r\n            \"startTime\": 1560835694425,\r\n            \"sequenceId\": 190,\r\n            \"endTime\": 1560835721000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835721172,\r\n                    \"trialJobId\": \"wcNTX\",\r\n                    \"parameterId\": \"190\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4802802810775693,\\\"test-rmse\\\":4.767764316499411}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835721172,\r\n                    \"trialJobId\": \"wcNTX\",\r\n                    \"parameterId\": \"190\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4802802810775693,\\\"test-rmse\\\":4.767764316499411}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"GNDHx\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 191,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 1,\r\n                    \"PT\": 0,\r\n                    \"TT\": 4\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/GNDHx\",\r\n            \"startTime\": 1560835694455,\r\n            \"sequenceId\": 191,\r\n            \"endTime\": 1560835721000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835720774,\r\n                    \"trialJobId\": \"GNDHx\",\r\n                    \"parameterId\": \"191\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2556924196526333,\\\"test-rmse\\\":4.039395335209618}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835720774,\r\n                    \"trialJobId\": \"GNDHx\",\r\n                    \"parameterId\": \"191\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.2556924196526333,\\\"test-rmse\\\":4.039395335209618}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"oxZBI\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 192,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 4,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/oxZBI\",\r\n            \"startTime\": 1560835694486,\r\n            \"sequenceId\": 192,\r\n            \"endTime\": 1560835722000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835721590,\r\n                    \"trialJobId\": \"oxZBI\",\r\n                    \"parameterId\": \"192\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3014601402444517,\\\"test-rmse\\\":4.408544800939597}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835721590,\r\n                    \"trialJobId\": \"oxZBI\",\r\n                    \"parameterId\": \"192\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.3014601402444517,\\\"test-rmse\\\":4.408544800939597}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"WCGyB\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 193,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 4,\r\n                    \"PT\": 2,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/WCGyB\",\r\n            \"startTime\": 1560835694530,\r\n            \"sequenceId\": 193,\r\n            \"endTime\": 1560835721000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835720945,\r\n                    \"trialJobId\": \"WCGyB\",\r\n                    \"parameterId\": \"193\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.452758148947186,\\\"test-rmse\\\":4.73664073753838}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835720945,\r\n                    \"trialJobId\": \"WCGyB\",\r\n                    \"parameterId\": \"193\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.452758148947186,\\\"test-rmse\\\":4.73664073753838}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"NcRww\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 194,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 0,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/NcRww\",\r\n            \"startTime\": 1560835734570,\r\n            \"sequenceId\": 194,\r\n            \"endTime\": 1560835754000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835753883,\r\n                    \"trialJobId\": \"NcRww\",\r\n                    \"parameterId\": \"194\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.1347336904235545,\\\"test-rmse\\\":5.912622954016006}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835753883,\r\n                    \"trialJobId\": \"NcRww\",\r\n                    \"parameterId\": \"194\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":4.1347336904235545,\\\"test-rmse\\\":5.912622954016006}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"uk4TG\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 195,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 3,\r\n                    \"PT\": 1,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/uk4TG\",\r\n            \"startTime\": 1560835734593,\r\n            \"sequenceId\": 195,\r\n            \"endTime\": 1560835754000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835753908,\r\n                    \"trialJobId\": \"uk4TG\",\r\n                    \"parameterId\": \"195\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.335817674415948,\\\"test-rmse\\\":4.53941202993029}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835753908,\r\n                    \"trialJobId\": \"uk4TG\",\r\n                    \"parameterId\": \"195\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.335817674415948,\\\"test-rmse\\\":4.53941202993029}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"btAzL\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 196,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 5,\r\n                    \"PT\": 2,\r\n                    \"TT\": 3\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/btAzL\",\r\n            \"startTime\": 1560835734615,\r\n            \"sequenceId\": 196,\r\n            \"endTime\": 1560835754000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835754171,\r\n                    \"trialJobId\": \"btAzL\",\r\n                    \"parameterId\": \"196\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4802802810775693,\\\"test-rmse\\\":4.767764316499411}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835754171,\r\n                    \"trialJobId\": \"btAzL\",\r\n                    \"parameterId\": \"196\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4802802810775693,\\\"test-rmse\\\":4.767764316499411}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"GqVU0\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 197,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 2,\r\n                    \"PT\": 5,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/GqVU0\",\r\n            \"startTime\": 1560835734637,\r\n            \"sequenceId\": 197,\r\n            \"endTime\": 1560835754000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835754090,\r\n                    \"trialJobId\": \"GqVU0\",\r\n                    \"parameterId\": \"197\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4208039705028863,\\\"test-rmse\\\":4.592784722139947}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835754090,\r\n                    \"trialJobId\": \"GqVU0\",\r\n                    \"parameterId\": \"197\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.4208039705028863,\\\"test-rmse\\\":4.592784722139947}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"wZ7cy\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 198,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 7,\r\n                    \"TT\": 2\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/wZ7cy\",\r\n            \"startTime\": 1560835734661,\r\n            \"sequenceId\": 198,\r\n            \"endTime\": 1560835754000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835754082,\r\n                    \"trialJobId\": \"wZ7cy\",\r\n                    \"parameterId\": \"198\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.453063098471348,\\\"test-rmse\\\":4.444702248341829}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835754082,\r\n                    \"trialJobId\": \"wZ7cy\",\r\n                    \"parameterId\": \"198\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.453063098471348,\\\"test-rmse\\\":4.444702248341829}\"\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"id\": \"mqxSw\",\r\n            \"status\": \"SUCCEEDED\",\r\n            \"hyperParameters\": {\r\n                \"parameter_id\": 199,\r\n                \"parameter_source\": \"algorithm\",\r\n                \"parameters\": {\r\n                    \"Dataset\": \"Bike\",\r\n                    \"City\": \"NYC\",\r\n                    \"CT\": 0,\r\n                    \"PT\": 3,\r\n                    \"TT\": 1\r\n                }\r\n            },\r\n            \"logPath\": \"file://localhost:/Users/chaidi/nni/experiments/rU6J0i83/trials/mqxSw\",\r\n            \"startTime\": 1560835734684,\r\n            \"sequenceId\": 199,\r\n            \"endTime\": 1560835754000,\r\n            \"finalMetricData\": [\r\n                {\r\n                    \"timestamp\": 1560835753809,\r\n                    \"trialJobId\": \"mqxSw\",\r\n                    \"parameterId\": \"199\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.702732583576403,\\\"test-rmse\\\":4.892015893561471}\"\r\n                }\r\n            ],\r\n            \"intermediate\": [\r\n                {\r\n                    \"timestamp\": 1560835753809,\r\n                    \"trialJobId\": \"mqxSw\",\r\n                    \"parameterId\": \"199\",\r\n                    \"type\": \"FINAL\",\r\n                    \"sequence\": 0,\r\n                    \"data\": \"{\\\"default\\\":3.702732583576403,\\\"test-rmse\\\":4.892015893561471}\"\r\n                }\r\n            ]\r\n        }\r\n    ]\r\n}"
  },
  {
    "path": "Experiments/ParameterSearch/search_space.json",
    "content": "{\r\n\r\n    \"Dataset\": {\"_type\": \"choice\", \"_value\": [\"DiDi\"]},\r\n    \"City\": {\"_type\": \"choice\", \"_value\": [\"Xian\"]},\r\n\r\n    \"CT\": {\"_type\": \"choice\", \"_value\": [6]},\r\n    \"PT\": {\"_type\": \"choice\", \"_value\": [7]},\r\n    \"TT\": {\"_type\": \"choice\", \"_value\": [4]},\r\n\r\n    \"K\": {\"_type\":\"choice\",\"_value\":[1]},\r\n    \"L\": {\"_type\":\"choice\",\"_value\":[1]},\r\n\r\n    \"Graph\": {\"_type\":\"choice\",\"_value\":[\"Distance-Interaction-Correlation\"]},\r\n\r\n    \"GLL\": {\"_type\":\"choice\",\"_value\":[1]},\r\n\r\n    \"LSTMUnits\": {\"_type\":\"choice\",\"_value\":[64]},\r\n\r\n    \"GALUnits\": {\"_type\":\"choice\", \"_value\": [64]},\r\n\r\n    \"DenseUnits\": {\"_type\":\"choice\",\"_value\":[32]},\r\n\r\n    \"BatchSize\": {\"_type\":\"choice\",\"_value\":[128]},\r\n\r\n    \"lr\": {\"_type\":\"choice\",\"_value\":[0.0001]},\r\n\r\n    \"TD\": {\"_type\":\"uniform\",\"_value\":[3000, 10000]},\r\n    \"TC\": {\"_type\":\"uniform\",\"_value\":[0.3, 0.7]},\r\n    \"TI\": {\"_type\":\"uniform\",\"_value\":[10, 100]}\r\n}"
  },
  {
    "path": "Experiments/ParameterSearch/xgboost_config.yml",
    "content": "authorName: DiChai\r\nexperimentName: xgboost_parameter_search\r\ntrialConcurrency: 2\r\nmaxExecDuration: 24h\r\nmaxTrialNum: 200\r\ntrainingServicePlatform: local\r\n# The path to Search Space\r\nsearchSpacePath: xgboost_search_space.json\r\nuseAnnotation: false\r\ntuner:\r\n  builtinTunerName: TPE\r\n# The path and the running command of trial\r\ntrial:\r\n  command: python CPT_XGBoost.py\r\n  codeDir: .\r\n  gpuNum: 0"
  },
  {
    "path": "Experiments/ParameterSearch/xgboost_search_space.json",
    "content": "{\r\n\r\n    \"Dataset\": {\"_type\": \"choice\", \"_value\": [\"Bike\"]},\r\n    \"City\": {\"_type\": \"choice\", \"_value\": [\"NYC\"]},\r\n\r\n    \"CT\": {\"_type\": \"choice\", \"_value\": [6]},\r\n    \"PT\": {\"_type\": \"choice\", \"_value\": [7]},\r\n    \"TT\": {\"_type\": \"choice\", \"_value\": [4]},\r\n\r\n    \"max_depth\": {\"_type\":\"randint\",\"_value\":[1, 20]},\r\n    \"num_boost_round\": {\"_type\":\"randint\",\"_value\":[50, 300]}\r\n}"
  },
  {
    "path": "Experiments/RegionGeneration/region_generation.py",
    "content": "import pandas as pd\nfrom UCTB.preprocess.RegionGenerator import RegionGenerator\nfrom UCTB.preprocess.dataset_helper import convert_uctb_data\n\n# NYC\n# initialize the configuration of the RegionGenerator\nspatial_range = []\narea_limit = 1\n\nregion_generator = RegionGenerator(spatial_range=spatial_range,area_limit=area_limit)\n\n# regions are created in self.regions\nregion_generator.partition(method='grid')\n\nservice_record_filepath = 'trip_record.csv'\ndf = pd.read_csv(service_record_filepath)\n\n# service records are binded in self.demand_matrix\nregion_generator.bind(df,method='location_based')\n\n# cluster elements to acquire regions with better charateristics\nregions,demand_matrix = region_generator.aggregate(cluster_method='node_swapping')\n\n\ntime_fitness = 5\ntime_range = ['2013-01-01','2014-01-01']\n\nuctb_data = convert_uctb_data(regions,demand_matrix,time_fitness,time_range)\n\n\n\n\n\n\n"
  },
  {
    "path": "Experiments/STGCN/Runner.py",
    "content": "import os\n\n# #############################################\n# # BenchMark Bike\n# #############################################\n# ########### NYC ########### --closeness_len 13 --period_len 0 --trend_len 0\n# os.system(\"python STGCN.py --dataset Bike --city NYC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # os.system(\"python STGCN.py --dataset Bike --city NYC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# os.system(\"python STGCN.py --dataset Bike --city NYC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n\n# # # ########### Chicago ###########\n# # # # os.system(\"python STGCN.py --dataset Bike --city Chicago --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # # # os.system(\"python STGCN.py --dataset Bike --city Chicago --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# os.system(\"python STGCN.py --dataset Bike --city Chicago --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n\n# # # ########### DC ###########\n# # # # os.system(\"python STGCN.py --dataset Bike --city DC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # # # os.system(\"python STGCN.py --dataset Bike --city DC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# os.system(\"python STGCN.py --dataset Bike --city DC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n\n\n# # # ###############################################\n# # # # BenchMark DiDi\n# # # ###############################################\n# # # ############# Xian #############\n# # # # os.system(\"python STGCN.py --dataset DiDi --city Xian --MergeIndex 3 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # # # os.system(\"python STGCN.py --dataset DiDi --city Xian --MergeIndex 6 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # os.system(\"python STGCN.py --dataset DiDi --city Xian --MergeIndex 12 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # # # ############# Chengdu #############\n# # # # # os.system(\"python STGCN.py --dataset DiDi --city Chengdu --MergeIndex 3 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # # # # os.system(\"python STGCN.py --dataset DiDi --city Chengdu --MergeIndex 6 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # os.system(\"python STGCN.py --dataset DiDi --city Chengdu --MergeIndex 12 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n\n\n# # # # ###############################################\n# # # # # BenchMark Metro\n# # # # ###############################################\n# # # # ############# Chongqing #############\n# # # # # os.system(\"python STGCN.py --dataset Metro --city Chongqing --MergeIndex 3 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # # # # os.system(\"python STGCN.py --dataset Metro --city Chongqing --MergeIndex 6 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # os.system(\"python STGCN.py --dataset Metro --city Chongqing --MergeIndex 12 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n\n# # # # ############# Shanghai #############\n# # # # # os.system(\"python STGCN.py --dataset Metro --city Shanghai --MergeIndex 3 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # # # # os.system(\"python STGCN.py --dataset Metro --city Shanghai --MergeIndex 6 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # os.system(\"python STGCN.py --dataset Metro --city Shanghai --MergeIndex 12 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n\n\n# # # # ###############################################\n# # # # # BenchMark ChargeStation\n# # # # ###############################################\n\n# # # # # os.system(\"python STGCN.py --dataset ChargeStation --city Beijing --MergeIndex 1 --MergeWay max --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # os.system(\"python STGCN.py --dataset ChargeStation --city Beijing --MergeIndex 2 --MergeWay max --closeness_len 13 --period_len 0 --trend_len 0\")\n\n\n\n# # # # ###############################################\n# # # # # BenchMark METR-LA\n# # # # ###############################################\n\n# # # # # os.system(\"python STGCN.py --dataset METR --city LA --MergeIndex 3 --MergeWay average --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # # # # os.system(\"python STGCN.py --dataset METR --city LA --MergeIndex 6 --MergeWay average --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# os.system(\"python STGCN.py --dataset METR --city LA --MergeIndex 12 --MergeWay average --closeness_len 13 --period_len 0 --trend_len 0\")\n\n\n# # # # ###############################################\n# # # # # BenchMark PEMS-BAY\n# # # # ###############################################\n# # # # # os.system(\"python STGCN.py --dataset PEMS --city BAY --MergeIndex 3 --MergeWay average --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # # # # os.system(\"python STGCN.py --dataset PEMS --city BAY --MergeIndex 6 --MergeWay average --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# os.system(\"python STGCN.py --dataset PEMS --city BAY --MergeIndex 12 --MergeWay average --closeness_len 13 --period_len 0 --trend_len 0\")\n\n\n\n# # # ############# Xian_Street #############\n# os.system(\"python STGCN.py --dataset DiDi --city Xian_Street --MergeIndex 3 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# os.system(\"python STGCN.py --dataset DiDi --city Xian_Street --MergeIndex 6 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# os.system(\"python STGCN.py --dataset DiDi --city Xian_Street --MergeIndex 12 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# # # ############# Chengdu_Street #############\n# os.system(\"python STGCN.py --dataset DiDi --city Chengdu_Street --MergeIndex 3 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# os.system(\"python STGCN.py --dataset DiDi --city Chengdu_Street --MergeIndex 6 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n# os.system(\"python STGCN.py --dataset DiDi --city Chengdu_Street --MergeIndex 12 --MergeWay sum --closeness_len 13 --period_len 0 --trend_len 0\")\n\n"
  },
  {
    "path": "Experiments/STGCN/STGCN.py",
    "content": "import os\nimport tensorflow as tf\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator,scaled_laplacian_STGCN\nimport argparse\n\nfrom UCTB.utils.utils_STGCN import model_test,model_train,data_gen\nfrom  UCTB.model.STGCN import cheb_poly_approx\nfrom UCTB.evaluation import metric\n\nos.environ[\"CUDA_VISIBLE_DEVICES\"] = \"1\"\nconfig = tf.ConfigProto()\nconfig.gpu_options.allow_growth = True\ntf.Session(config=config)\n\n#args config\nparser = argparse.ArgumentParser()\nparser.add_argument('--n_his', type=int, default=12)\nparser.add_argument('--n_pred', type=int, default=1)\nparser.add_argument('--batch_size', type=int, default=32)\nparser.add_argument('--epoch', type=int, default=400)\nparser.add_argument('--save', type=int, default=5)\nparser.add_argument('--ks', type=int, default=3)\nparser.add_argument('--kt', type=int, default=3)\nparser.add_argument('--lr', type=float, default=1e-3)\nparser.add_argument('--opt', type=str, default='RMSProp')\nparser.add_argument('--graph', type=str, default='default')\nparser.add_argument('--inf_mode', type=str, default='sep')\n\n\n# data loader parameters\nparser.add_argument(\"--dataset\", default='Bike', type=str,help=\"configuration file path\")\nparser.add_argument(\"--city\", default='NYC', type=str)\nparser.add_argument(\"--closeness_len\", default=6, type=int)\nparser.add_argument(\"--period_len\", default=7, type=int)\nparser.add_argument(\"--trend_len\", default=4, type=int)\nparser.add_argument(\"--data_range\", default=\"all\", type=str)\nparser.add_argument(\"--train_data_length\", default=\"all\", type=str)\nparser.add_argument(\"--test_ratio\", default=0.1, type=float)\nparser.add_argument(\"--MergeIndex\", default=1, type=int)\nparser.add_argument(\"--MergeWay\", default=\"sum\", type=str)\n\nargs = parser.parse_args()\nargs.n_his = args.closeness_len + args.period_len+args.trend_len\nn_his, n_pred = args.n_his, args.n_pred\nKs, Kt = args.ks, args.kt\n\n# blocks: settings of channel size in st_conv_blocks / bottleneck design\nblocks = [[1, 32, 64], [64, 32, 128]]\n\n# loading dataset\ndata_loader = NodeTrafficLoader(dataset=args.dataset, city=args.city,\n                                    data_range=args.data_range, train_data_length=args.train_data_length,\n                                    test_ratio=float(args.test_ratio),\n                                    closeness_len=args.closeness_len,\n                                    period_len=args.period_len,\n                                    trend_len=args.trend_len,\n                                    normalize=False,\n                                    MergeIndex=args.MergeIndex,\n                                    MergeWay=args.MergeWay)\n\ngraph_obj = GraphGenerator(graph='distance', data_loader=data_loader)\n\n# data loading\ndataset_obj = data_gen(data_loader)\nn = graph_obj.AM.shape[-1]\nargs.n_route = n\n\nprint(f'>> Loading dataset with Mean: {dataset_obj.mean:.2f}, STD: {dataset_obj.std:.2f}')\nW = graph_obj.AM[0]\n\nmodel_name = os.path.join(os.path.abspath(\"./model_dir/\"),\"{}_{}_{}\".format(args.dataset,args.city,args.MergeIndex))\n\n\n# Calculate graph kernel\nL = scaled_laplacian_STGCN(W) # L with shape [n_route, n_route]\n# Alternative approximation method: 1st approx - first_approx(W, n).\nLk = cheb_poly_approx(L, Ks, n)\ntf.add_to_collection(name='graph_kernel', value=tf.cast(tf.constant(Lk), tf.float32))\n\n\n# # Train\nmodel_train(dataset_obj, blocks, args, model_name)\n\n# Test\ntest_prediction = model_test(dataset_obj, dataset_obj.get_len('test'), n_his, n_pred, args.inf_mode, load_path=model_name)\n\n# de normalization here\n\ntest_prediction = data_loader.normalizer.inverse_transform(test_prediction)\ny_true = data_loader.normalizer.inverse_transform(data_loader.test_y)\ntest_rmse = metric.rmse(prediction=test_prediction.squeeze(),\n                        target=y_true.squeeze())\n\n\nprint('Test RMSE', test_rmse)"
  },
  {
    "path": "Experiments/STMeta/RunnerCPTtrial.py",
    "content": "import os\n###############################################\n# C P T trial\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:1,closeness_len:12,period_len:14,trend_len:8')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:2,closeness_len:12,period_len:14,trend_len:8')"
  },
  {
    "path": "Experiments/STMeta/RunnerLSTM.py",
    "content": "import os\n\n############################################################################################################\n# TMeta\n############################################################################################################\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n          ' -p graph:Distance,st_method:LSTM,model_version:LSTM,mark:V0')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n          ' -p graph:Distance,st_method:LSTM,model_version:LSTM,mark:V0')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n          ' -p graph:Distance,st_method:LSTM,model_version:LSTM,mark:V0')"
  },
  {
    "path": "Experiments/STMeta/RunnerStreetDiDi.py",
    "content": "import os\n\n###############################################\n# BenchMark DiDi\n###############################################\n############# Xian #############\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian_street.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian_street.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian_street.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian_street.data.yml -p graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian_street.data.yml -p graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian_street.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n############# Chengdu #############\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu_street.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu_street.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu_street.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu_street.data.yml -p graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu_street.data.yml -p graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu_street.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu_street.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n"
  },
  {
    "path": "Experiments/STMeta/RunnerWWW.py",
    "content": "import os\n\n#############################################\n# BenchMark Bike\n#############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'graph:Correlation,gcn_k:2,mark:BenchMark2,gclstm_layers:2')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'graph:Correlation,gcn_k:3,mark:BenchMark3,gclstm_layers:3')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p graph:Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p graph:Interaction')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n          '-p graph:Distance-Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p graph:Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p graph:Interaction')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n          '-p graph:Distance-Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml -p graph:Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml -p graph:Interaction')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n          '-p graph:Distance-Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\n\n\n# ###############################################\n# # BenchMark DiDi\n# ###############################################\n#\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml -p graph:Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml -p graph:Interaction')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\n#\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml -p graph:Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml -p graph:Interaction')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,gcn_k:1,gclstm_layers:1,batch_size:16,mark:K11')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,gcn_k:1,gclstm_layers:2,batch_size:32,mark:K12')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,gcn_k:1,gclstm_layers:3,batch_size:32,mark:K13')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,gcn_k:2,gclstm_layers:1,batch_size:16,mark:K21')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,gcn_k:3,gclstm_layers:1,batch_size:16,mark:K31')\n\n###############################################\n# BenchMark Metro\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml -p graph:Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml -p graph:Line')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p graph:Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p graph:Line')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,gclstm_layers:1,gcn_k:3,mark:BM13')\n\n###############################################\n# BenchMark ChargeStation\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n            ' -d chargestation_beijing.data.yml -p graph:Distance')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation')\n"
  },
  {
    "path": "Experiments/STMeta/Runner_GRU.py",
    "content": "import os\n\n#############################################\n# BenchMark Bike\n#############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\n\n\n# ###############################################\n# # BenchMark DiDi\n# ###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml '\n          '-p mark:V0')\n\n###############################################\n# BenchMark Metro\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance')\n#\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line')\n\n###############################################\n# BenchMark ChargeStation\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance,mark:V0')\n"
  },
  {
    "path": "Experiments/STMeta/Runner_M1_0.py",
    "content": "import os\n\n############################################################################################################\n# Enrich gcn_k\n############################################################################################################\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:BM211')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:BM211')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:BM211')"
  },
  {
    "path": "Experiments/STMeta/Runner_M1_1.py",
    "content": "import os\n\n############################################################################################################\n# Enrich gcn_k\n############################################################################################################\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:BM211')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:BM211')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:128,mark:BM211')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:128,mark:BM211')"
  },
  {
    "path": "Experiments/STMeta/Runner_M2_0.py",
    "content": "import os\n\n############################################################################################################\n# Enrich gcn_k\n############################################################################################################\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:BM211')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:BM211')"
  },
  {
    "path": "Experiments/STMeta/Runner_M2_1.py",
    "content": "import os\n\n############################################################################################################\n# Enrich gcn_k\n############################################################################################################\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d chargestation_beijing.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:BM211')"
  },
  {
    "path": "Experiments/STMeta/Runner_Main.py",
    "content": "import os\n\n#############################################\n# BenchMark Bike\n#############################################\n########### NYC ###########\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n          ' -p data_range:0.125,train_data_length:60,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n          ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n          ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.125,train_data_length:60,graph:Distance,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n          '-p data_range:0.125,train_data_length:60,graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n          '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n          '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n          '-p data_range:0.125,train_data_length:60,graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n          '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n          '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n          '-p data_range:0.125,train_data_length:60,graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n          '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n          '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n########### Chicago ###########\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n          ' -p data_range:0.125,train_data_length:60,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n          ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n          ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.125,train_data_length:60,graph:Distance,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n          '-p data_range:0.125,train_data_length:60,graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n          '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n          '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n          '-p data_range:0.125,train_data_length:60,graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n          '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n          '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n          '-p data_range:0.125,train_data_length:60,graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n          '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n          '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n############# DC #############\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n          ' -p data_range:0.125,train_data_length:60,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n          ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n          ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.125,train_data_length:60,graph:Distance,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p graph:Distance,MergeIndex:12')\n\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n          '-p data_range:0.125,train_data_length:60,graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n          '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n          '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n          '-p data_range:0.125,train_data_length:60,graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n          '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n          '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n          '-p data_range:0.125,train_data_length:60,graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n          '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n          '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n\n\n###############################################\n# BenchMark DiDi\n###############################################\n############# Xian #############\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n############# Chengdu #############\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n          '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n\n###############################################\n# BenchMark Metro\n###############################################\n############# Chongqing #############\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:12')\n\n############# Shanghai #############\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line,MergeIndex:12')\n\n###############################################\n# BenchMark ChargeStation\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:2')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:2')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n\n\n###############################################\n# BenchMark METR-LA\n###############################################\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n\n\n###############################################\n# BenchMark PEMS-BAY\n###############################################\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n          ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:1')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')"
  },
  {
    "path": "Experiments/STMeta/Runner_PS_Chicago.py",
    "content": "import os\n\n############################################################################################################\n# Enrich gcn_k\n############################################################################################################\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:16,mark:PS1')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:16,mark:PS2')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:16,mark:PS3')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:32,mark:PS4')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:32,mark:PS5')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:32,mark:PS6')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:PS7')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:PS8')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:PS9')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:16,train_data_length:all,mark:PS10')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:16,train_data_length:all,mark:PS11')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:16,train_data_length:all,mark:PS12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:32,train_data_length:all,mark:PS13')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:32,train_data_length:all,mark:PS14')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:32,train_data_length:all,mark:PS15')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:64,train_data_length:all,mark:PS16')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,train_data_length:all,mark:PS17')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:64,train_data_length:all,mark:PS18')"
  },
  {
    "path": "Experiments/STMeta/Runner_PS_NYC.py",
    "content": "import os\n\n############################################################################################################\n# Enrich gcn_k\n############################################################################################################\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:16,mark:PS1')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:16,mark:PS2')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:16,mark:PS3')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:32,mark:PS4')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:32,mark:PS5')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:32,mark:PS6')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:PS7')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:PS8')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:PS9')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:16,train_data_length:all,mark:PS10')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:16,train_data_length:all,mark:PS11')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:16,train_data_length:all,mark:PS12')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:32,train_data_length:all,mark:PS13')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:32,train_data_length:all,mark:PS14')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:32,train_data_length:all,mark:PS15')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:64,train_data_length:all,mark:PS16')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,train_data_length:all,mark:PS17')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:64,train_data_length:all,mark:PS18')"
  },
  {
    "path": "Experiments/STMeta/Runner_PS_Shanghai.py",
    "content": "import os\n\n############################################################################################################\n# Enrich gcn_k\n############################################################################################################\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:16,mark:PS1')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:16,mark:PS2')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:16,mark:PS3')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:32,mark:PS4')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:32,mark:PS5')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:32,mark:PS6')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p '\n          'gcn_k:1,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:PS7')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p '\n          'gcn_k:2,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:PS8')\n\nos.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml -p '\n          'gcn_k:3,gcn_layers:1,gclstm_layers:1,batch_size:64,mark:PS9')"
  },
  {
    "path": "Experiments/STMeta/Runner_singleGraph.py",
    "content": "import os\n\n#############################################\n# BenchMark Bike\n#############################################\n########### NYC ###########\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n#           '-p graph:Distance,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n#           '-p graph:Correlation,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n#           '-p graph:Interaction,MergeIndex:12')\n\n# ########### Chicago ###########\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n#           '-p graph:Distance,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n#           '-p graph:Correlation,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n#           '-p graph:Interaction,MergeIndex:12')\n\n# ############# DC #############\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n#           '-p graph:Distance,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n#           '-p graph:Correlation,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n          '-p graph:Interaction,MergeIndex:12')\n\n###############################################\n# BenchMark DiDi\n###############################################\n############# Xian #############\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n#           '-p graph:Distance,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n#           '-p graph:Correlation,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n#           '-p graph:Interaction,MergeIndex:12')\n\n# # ############# Chengdu #############\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n#           '-p graph:Distance,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n#           '-p graph:Correlation,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n#           '-p graph:Interaction,MergeIndex:12')\n\n###############################################\n# BenchMark Metro\n###############################################\n############# Chongqing #############\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n#           '-p graph:Distance,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n#           '-p graph:Correlation,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n#           '-p graph:Line,MergeIndex:12')\n\n# # ############# Shanghai #############\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n#           '-p graph:Distance,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n#           '-p graph:Correlation,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n#           '-p graph:Line,MergeIndex:12')\n\n# ###############################################\n# # BenchMark ChargeStation\n# ###############################################\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n#           ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:2')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n#           ' -d chargestation_beijing.data.yml -p graph:Correlation,MergeIndex:2')\n\n###############################################\n# BenchMark METR-LA\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d metr_la.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d metr_la.data.yml -p graph:Correlation,MergeIndex:12')\n\n###############################################\n# BenchMark PEMS-BAY\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n          ' -d pems_bay.data.yml -p graph:Correlation,MergeIndex:12')"
  },
  {
    "path": "Experiments/STMeta/Runner_temporalAblation.py",
    "content": "import os\n\n#############################################\n# BenchMark Bike\n#############################################\n########### NYC ###########\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n          '-p period_len:0,trend_len:0,graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n          '-p trend_len:0,graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n#           '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n########### Chicago ###########\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n          '-p period_len:0,trend_len:0,graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n          '-p trend_len:0,graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n#           '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n############# DC #############\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n          '-p period_len:0,trend_len:0,graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n          '-p trend_len:0,graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n#           '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n\n###############################################\n# BenchMark DiDi\n###############################################\n############# Xian #############\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n          '-p period_len:0,trend_len:0,graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n          '-p trend_len:0,graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n#           '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n\n############# Chengdu #############\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n          '-p period_len:0,trend_len:0,graph:Distance-Correlation-Interaction,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n          '-p trend_len:0,graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n#           '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n\n\n###############################################\n# BenchMark Metro\n###############################################\n############# Chongqing #############\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n          '-p period_len:0,trend_len:0,graph:Distance-Correlation-Line,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n          '-p trend_len:0,graph:Distance-Correlation-Line,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n#           '-p graph:Distance-Correlation-Line,MergeIndex:12')\n\n############# Shanghai #############\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n          '-p period_len:0,trend_len:0,graph:Distance-Correlation-Line,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n          '-p trend_len:0,graph:Distance-Correlation-Line,MergeIndex:12')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n#           '-p graph:Distance-Correlation-Line,MergeIndex:12')\n\n\n###############################################\n# BenchMark ChargeStation\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d chargestation_beijing.data.yml '\n          ' -p period_len:0,trend_len:0,graph:Distance-Correlation,MergeIndex:2')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d chargestation_beijing.data.yml '\n          ' -p trend_len:0,graph:Distance-Correlation,MergeIndex:2')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d chargestation_beijing.data.yml '\n          ' -p graph:Distance-Correlation,MergeIndex:2')\n\n\n###############################################\n# BenchMark METR-LA\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metr_la.data.yml '\n          ' -p period_len:0,trend_len:0,graph:Distance-Correlation,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metr_la.data.yml '\n          ' -p trend_len:0,graph:Distance-Correlation,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metr_la.data.yml '\n          ' -p graph:Distance-Correlation,MergeIndex:12')\n\n\n###############################################\n# BenchMark PEMS-BAY\n###############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d pems_bay.data.yml'\n          ' -p period_len:0,trend_len:0,graph:Distance-Correlation,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d pems_bay.data.yml'\n          ' -p trend_len:0,graph:Distance-Correlation,MergeIndex:12')\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d pems_bay.data.yml'\n          ' -p graph:Distance-Correlation,MergeIndex:12')\n"
  },
  {
    "path": "Experiments/STMeta/Runner_v3.py",
    "content": "import os\n\n#############################################\n# BenchMark Bike\n#############################################\n\nos.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n          '-p graph:Distance-Correlation-Interaction')\n#\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n#           '-p graph:Distance-Correlation-Interaction')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n#           '-p graph:Distance-Correlation-Interaction')\n\n\n# ###############################################\n# # BenchMark DiDi\n# ###############################################\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n#           '-p graph:Distance-Correlation-Interaction')\n#\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n#           '-p graph:Distance-Correlation-Interaction')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n#           '-p graph:Distance-Correlation-Interaction,gcn_k:1,gclstm_layers:2,mark:K12')\n#\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n#           '-p graph:Distance-Correlation-Interaction,gcn_k:1,gclstm_layers:3,mark:K13')\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n#           '-p graph:Distance-Correlation-Interaction,gcn_k:3,gclstm_layers:3,batch_size:8,mark:K33')\n\n###############################################\n# BenchMark Metro\n###############################################\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n#           '-p graph:Distance-Correlation-Line')\n#\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n#           '-p graph:Distance-Correlation-Line')\n\n###############################################\n# BenchMark ChargeStation\n###############################################\n\n# os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n#           ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation')\n"
  },
  {
    "path": "Experiments/STMeta/STMeta_Obj.py",
    "content": "import os\nimport nni\nimport yaml\nimport argparse\nimport GPUtil\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.time_utils import is_work_day_china, is_work_day_america\n\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\nfrom UCTB.preprocess import SplitData\n#####################################################################\n# argument parser\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\nparser.add_argument('-m', '--model', default='STMeta_v0.model.yml')\nparser.add_argument('-d', '--data', default='didi_chengdu.data.yml')\nparser.add_argument('-p', '--update_params', default='')\n\n# Parse params\nterminal_vars = vars(parser.parse_args())\nyml_files = [terminal_vars['model'], terminal_vars['data']]\nargs = {}\nfor yml_file in yml_files:\n    with open(yml_file, 'r') as f:\n        args.update(yaml.load(f))\n\nif len(terminal_vars['update_params']) > 0:\n    args.update({e.split(':')[0]: e.split(':')[1] for e in terminal_vars['update_params'].split(',')})\n    print({e.split(':')[0]: e.split(':')[1] for e in terminal_vars['update_params'].split(',')})\n\nnni_params = nni.get_next_parameter()\nnni_sid = nni.get_sequence_id()\nif nni_params:\n    args.update(nni_params)\n    args['mark'] += str(nni_sid)\n\n#####################################################################\n# Generate code_version\ncode_version = '{}_C{}P{}T{}_G{}_K{}L{}_F{}_{}'.format(args['model_version'],\n                                                       args['closeness_len'], args['period_len'],args['trend_len'],\n                                                       ''.join([e[0] for e in args['graph'].split('-')]),\n                                                       args['gcn_k'], args['gcn_layers'], int(args[\"MergeIndex\"])*5, args['mark'])\nmodel_dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'model_dir')\nmodel_dir_path = os.path.join(model_dir_path, args['group'])\n#####################################################################\n\ndata_loader = NodeTrafficLoader(dataset=args['dataset'], city=args['city'],\n                                data_range=args['data_range'], train_data_length=args['train_data_length'],\n                                test_ratio=float(args['test_ratio']),\n                                closeness_len=args['closeness_len'],\n                                period_len=args['period_len'],\n                                trend_len=args['trend_len'],\n                                normalize=args['normalize'],\n                                with_tpe=args['with_tpe'],\n                                workday_parser=is_work_day_america if args['dataset'] == 'Bike' else is_work_day_china,\n                                MergeIndex=args['MergeIndex'],\n                                MergeWay=args[\"MergeWay\"])\n\n# split data\ntrain_closeness, val_closeness = SplitData.split_data(data_loader.train_closeness, [0.9, 0.1])\ntrain_period, val_period = SplitData.split_data(data_loader.train_period, [0.9, 0.1])\ntrain_trend, val_trend = SplitData.split_data(data_loader.train_trend, [0.9, 0.1])\ntrain_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\ntrain_ef, val_ef = SplitData.split_data(data_loader.train_ef, [0.9, 0.1])\n\n# build graphs\ngraph_obj = GraphGenerator(graph=args['graph'],\n                           data_loader=data_loader,\n                           threshold_distance=args['threshold_distance'],\n                           threshold_correlation=args['threshold_correlation'],\n                           threshold_interaction=args['threshold_interaction'])\n\nprint(\"TimeFitness\", data_loader.dataset.time_fitness)\nprint(\"TimeRange\", data_loader.dataset.time_range)\n\nde_normalizer = None if args['normalize'] is False else data_loader.normalizer.inverse_transform\n\ndeviceIDs = GPUtil.getAvailable(order='last', limit=8, maxLoad=1, maxMemory=0.7,\n                                includeNan=False, excludeID=[], excludeUUID=[])\n\nif len(deviceIDs) == 0:\n    current_device = '-1'\nelse:\n    if nni_params:\n        current_device = str(deviceIDs[int(nni_sid) % len(deviceIDs)])\n    else:\n        current_device = str(deviceIDs[0])\n\n\nSTMeta_obj = STMeta(num_node=data_loader.station_number,\n                    num_graph=graph_obj.LM.shape[0],\n                    external_dim=data_loader.external_dim,\n                    closeness_len=args['closeness_len'],\n                    period_len=args['period_len'],\n                    trend_len=args['trend_len'],\n                    input_dim=2 if args['with_tpe'] else 1,\n                    gcn_k=int(args.get('gcn_k', 0)),\n                    gcn_layers=int(args.get('gcn_layers', 0)),\n                    gclstm_layers=int(args['gclstm_layers']),\n                    num_hidden_units=args['num_hidden_units'],\n                    num_dense_units=args['num_filter_conv1x1'],\n                    # temporal attention parameters\n                    tpe_dim=data_loader.tpe_dim,\n                    temporal_gal_units=args.get('temporal_gal_units'),\n                    temporal_gal_num_heads=args.get('temporal_gal_num_heads'),\n                    temporal_gal_layers=args.get('temporal_gal_layers'),\n                    # merge parameters\n                    graph_merge_gal_units=args['graph_merge_gal_units'],\n                    graph_merge_gal_num_heads=args['graph_merge_gal_num_heads'],\n                    temporal_merge_gal_units=args['temporal_merge_gal_units'],\n                    temporal_merge_gal_num_heads=args['temporal_merge_gal_num_heads'],\n                    # network structure parameters\n                    st_method=args['st_method'],  # gclstm\n                    temporal_merge=args['temporal_merge'],  # gal\n                    graph_merge=args['graph_merge'],  # concat\n                    build_transfer=args['build_transfer'],\n                    lr=float(args['lr']),\n                    code_version=code_version,\n                    model_dir=model_dir_path,\n                    gpu_device=current_device)\n\nSTMeta_obj.build()\n\nprint(args['dataset'], args['city'], code_version)\nprint('Number of trainable variables', STMeta_obj.trainable_vars)\nprint('Number of training samples', data_loader.train_sequence_len)\n\n# # Training\nif args['train']:\n    STMeta_obj.fit(closeness_feature=data_loader.train_closeness,\n                   period_feature=data_loader.train_period,\n                   trend_feature=data_loader.train_trend,\n                   laplace_matrix=graph_obj.LM,\n                   target=data_loader.train_y,\n                   external_feature=data_loader.train_ef,\n                   sequence_length=data_loader.train_sequence_len,\n                   output_names=('loss', ),\n                   evaluate_loss_name='loss',\n                   op_names=('train_op', ),\n                   batch_size=int(args['batch_size']),\n                   max_epoch=int(args['max_epoch']),\n                   validate_ratio=0.1,\n                   early_stop_method='t-test',\n                   early_stop_length=args['early_stop_length'],\n                   early_stop_patience=args['early_stop_patience'],\n                   verbose=True,\n                   save_model=True)\n\nSTMeta_obj.load(code_version)\n\n# val prediction\nprediction = STMeta_obj.predict(closeness_feature=val_closeness,\n                                period_feature=val_period,\n                                trend_feature=val_trend,\n                                laplace_matrix=graph_obj.LM,\n                                target=val_y,\n                                external_feature=val_ef,\n                                output_names=('prediction', ),\n                                sequence_length=max(\n                                    (len(val_closeness), len(val_period), len(val_trend))),\n                                cache_volume=int(args['batch_size']), )\nval_prediction = prediction['prediction']\n\n# test prediction\nprediction = STMeta_obj.predict(closeness_feature=data_loader.test_closeness,\n                                period_feature=data_loader.test_period,\n                                trend_feature=data_loader.test_trend,\n                                laplace_matrix=graph_obj.LM,\n                                target=data_loader.test_y,\n                                external_feature=data_loader.test_ef,\n                                output_names=('prediction', ),\n                                sequence_length=data_loader.test_sequence_len,\n                                cache_volume=int(args['batch_size']), )\n\ntest_prediction = prediction['prediction']\n\nif de_normalizer:\n    test_prediction = de_normalizer(test_prediction)\n    data_loader.test_y = de_normalizer(data_loader.test_y)\n    val_prediction = de_normalizer(val_prediction)\n    val_y = de_normalizer(val_y)\n\ntest_rmse = metric.rmse(prediction=test_prediction, target=data_loader.test_y)\nval_rmse = metric.rmse(prediction=val_prediction, target=val_y)\n\n# Evaluate loss during training \nval_loss = STMeta_obj.load_event_scalar('val_loss')\n# best_val_loss = min([e[-1] for e in val_loss])\n# if de_normalizer:\n#     best_val_loss = de_normalizer(best_val_loss)\n# print('Best val result', best_val_loss)\n\nprint('Val result', val_rmse)\nprint('Test result', test_rmse)\ntime_consumption = [val_loss[e][0] - val_loss[e-1][0] for e in range(1, len(val_loss))]\ntime_consumption = sum([e for e in time_consumption if e < (min(time_consumption) * 10)]) / 3600\nprint('Converged using %.2f hour / %s epochs' % (time_consumption, STMeta_obj._global_step))\n\n# if nni_params:\n#     nni.report_final_result({\n#         'default': best_val_loss,\n#         'test-rmse': test_rmse,\n#         'test-mape': test_mape\n#     })\n"
  },
  {
    "path": "Experiments/STMeta/STMeta_Obj_time.py",
    "content": "import os\nimport yaml\nimport argparse\nimport GPUtil\nimport numpy as np\nfrom time import time\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.time_utils import is_work_day_china, is_work_day_america\n\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\nfrom UCTB.preprocess import Normalizer, SplitData\n#####################################################################\n# argument parser\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\nparser.add_argument('-m', '--model', default='STMeta_v0.model.yml')\nparser.add_argument('-d', '--data', default='didi_chengdu.data.yml')\nparser.add_argument('-p', '--update_params', default='')\n\n# Parse params\nterminal_vars = vars(parser.parse_args())\nyml_files = [terminal_vars['model'], terminal_vars['data']]\nargs = {}\nfor yml_file in yml_files:\n    with open(yml_file, 'r') as f:\n        args.update(yaml.load(f))\n\nif len(terminal_vars['update_params']) > 0:\n    args.update({e.split(':')[0]: e.split(':')[1] for e in terminal_vars['update_params'].split(',')})\n    print({e.split(':')[0]: e.split(':')[1] for e in terminal_vars['update_params'].split(',')})\n\n\n#####################################################################\n# Generate code_version\ncode_version = '{}_C{}P{}T{}_G{}_K{}L{}_F{}_{}'.format(args['model_version'],\n                                                       args['closeness_len'], args['period_len'],args['trend_len'],\n                                                       ''.join([e[0] for e in args['graph'].split('-')]),\n                                                       args['gcn_k'], args['gcn_layers'], int(args[\"MergeIndex\"])*5, args['mark'])\nmodel_dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'model_dir')\nmodel_dir_path = os.path.join(model_dir_path, args['group'])\n#####################################################################\n\ndata_loader = NodeTrafficLoader(dataset=args['dataset'], city=args['city'],\n                                data_range=args['data_range'], train_data_length=args['train_data_length'],\n                                test_ratio=float(args['test_ratio']),\n                                closeness_len=int(args['closeness_len']),\n                                period_len=int(args['period_len']),\n                                trend_len=int(args['trend_len']),\n                                normalize=args['normalize'],\n                                with_tpe=args['with_tpe'],\n                                workday_parser=is_work_day_america if args['dataset'] == 'Bike' else is_work_day_china,\n                                MergeIndex=args['MergeIndex'],\n                                MergeWay=args[\"MergeWay\"])\n\n# split data\ntrain_closeness, val_closeness = SplitData.split_data(data_loader.train_closeness, [0.9, 0.1])\ntrain_period, val_period = SplitData.split_data(data_loader.train_period, [0.9, 0.1])\ntrain_trend, val_trend = SplitData.split_data(data_loader.train_trend, [0.9, 0.1])\ntrain_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\ntrain_ef, val_ef = SplitData.split_data(data_loader.train_ef, [0.9, 0.1])\n\n# build graphs\ngraph_obj = GraphGenerator(graph=args['graph'],\n                           data_loader=data_loader,\n                           threshold_distance=args['threshold_distance'],\n                           threshold_correlation=args['threshold_correlation'],\n                           threshold_interaction=args['threshold_interaction'])\n\nprint(\"TimeFitness\", data_loader.dataset.time_fitness)\nprint(\"TimeRange\", data_loader.dataset.time_range)\n\nde_normalizer = None if args['normalize'] is False else data_loader.normalizer.inverse_transform\n\ndeviceIDs = GPUtil.getAvailable(order='last', limit=8, maxLoad=1, maxMemory=0.2,\n                                includeNan=False, excludeID=[], excludeUUID=[])\n\nif len(deviceIDs) == 0:\n    current_device = '-1'\nelse:\n    current_device = str(deviceIDs[0])\n\nprint(\"current_device:\",current_device)\n\nSTMeta_obj = STMeta(num_node=data_loader.station_number,\n                    num_graph=graph_obj.LM.shape[0],\n                    external_dim=data_loader.external_dim,\n                    closeness_len=args['closeness_len'],\n                    period_len=args['period_len'],\n                    trend_len=args['trend_len'],\n                    input_dim=2 if args['with_tpe'] else 1,\n                    gcn_k=int(args.get('gcn_k', 0)),\n                    gcn_layers=int(args.get('gcn_layers', 0)),\n                    gclstm_layers=int(args['gclstm_layers']),\n                    num_hidden_units=args['num_hidden_units'],\n                    num_dense_units=args['num_filter_conv1x1'],\n                    # temporal attention parameters\n                    tpe_dim=data_loader.tpe_dim,\n                    temporal_gal_units=args.get('temporal_gal_units'),\n                    temporal_gal_num_heads=args.get('temporal_gal_num_heads'),\n                    temporal_gal_layers=args.get('temporal_gal_layers'),\n                    # merge parameters\n                    graph_merge_gal_units=args['graph_merge_gal_units'],\n                    graph_merge_gal_num_heads=args['graph_merge_gal_num_heads'],\n                    temporal_merge_gal_units=args['temporal_merge_gal_units'],\n                    temporal_merge_gal_num_heads=args['temporal_merge_gal_num_heads'],\n                    # network structure parameters\n                    st_method=args['st_method'],  # gclstm\n                    temporal_merge=args['temporal_merge'],  # gal\n                    graph_merge=args['graph_merge'],  # concat\n                    build_transfer=args['build_transfer'],\n                    lr=float(args['lr']),\n                    code_version=code_version,\n                    model_dir=model_dir_path,\n                    gpu_device=current_device)\n\nSTMeta_obj.build()\n\nprint(args['dataset'], args['city'], code_version)\nprint('Number of trainable variables', STMeta_obj.trainable_vars)\nprint('Number of training samples', data_loader.train_sequence_len)\n\n# # Training\nstart_time = time()\nif args['train']:\n    STMeta_obj.fit(closeness_feature=data_loader.train_closeness,\n                   period_feature=data_loader.train_period,\n                   trend_feature=data_loader.train_trend,\n                   laplace_matrix=graph_obj.LM,\n                   target=data_loader.train_y,\n                   external_feature=data_loader.train_ef,\n                   sequence_length=data_loader.train_sequence_len,\n                   output_names=('loss', ),\n                   evaluate_loss_name='loss',\n                   op_names=('train_op', ),\n                   batch_size=int(args['batch_size']),\n                   max_epoch=int(args['max_epoch']),\n                   validate_ratio=0.1,\n                   early_stop_method='t-test',\n                   early_stop_length=args['early_stop_length'],\n                   early_stop_patience=args['early_stop_patience'],\n                   verbose=True,\n                   save_model=True)\nprint('Training time: %.8f seconds' % (time() - start_time))\n\nSTMeta_obj.load(code_version)\n\n# val prediction\nprediction = STMeta_obj.predict(closeness_feature=val_closeness,\n                                period_feature=val_period,\n                                trend_feature=val_trend,\n                                laplace_matrix=graph_obj.LM,\n                                target=val_y,\n                                external_feature=val_ef,\n                                output_names=('prediction', ),\n                                sequence_length=max(\n                                    (len(val_closeness), len(val_period), len(val_trend))),\n                                cache_volume=int(args['batch_size']), )\nval_prediction = prediction['prediction']\n\nstart_time = time()\n# test prediction\nprediction = STMeta_obj.predict(closeness_feature=data_loader.test_closeness,\n                                period_feature=data_loader.test_period,\n                                trend_feature=data_loader.test_trend,\n                                laplace_matrix=graph_obj.LM,\n                                target=data_loader.test_y,\n                                external_feature=data_loader.test_ef,\n                                output_names=('prediction', ),\n                                sequence_length=data_loader.test_sequence_len,\n                                cache_volume=int(args['batch_size']), )\nprint('Testing time: %.8f seconds' % (time() - start_time))\n\ntest_prediction = prediction['prediction']\n\nif de_normalizer:\n    test_prediction = de_normalizer(test_prediction)\n    data_loader.test_y = de_normalizer(data_loader.test_y)\n    val_prediction = de_normalizer(val_prediction)\n    val_y = de_normalizer(val_y)\n\ntest_rmse = metric.rmse(prediction=test_prediction, target=data_loader.test_y)\nval_rmse = metric.rmse(prediction=val_prediction, target=val_y)\n\n# Evaluate loss during training \nval_loss = STMeta_obj.load_event_scalar('val_loss')\n# best_val_loss = min([e[-1] for e in val_loss])\n# if de_normalizer:\n#     best_val_loss = de_normalizer(best_val_loss)\n# print('Best val result', best_val_loss)\n\nprint('Val result', val_rmse )\nprint('Test result', test_rmse)\ntime_consumption = [val_loss[e][0] - val_loss[e-1][0] for e in range(1, len(val_loss))]\ntime_consumption = sum([e for e in time_consumption if e < (min(time_consumption) * 10)]) / 3600\nprint('Converged using %.2f hour / %s epochs' % (time_consumption, STMeta_obj._global_step))\n\n"
  },
  {
    "path": "Experiments/STMeta/STMeta_v0.model.yml",
    "content": "# network structure parameters\nst_method: 'LSTM'\ntemporal_merge: 'gal'\ngraph_merge: 'gal'\n\n# gcn parameters\ngcn_k: 0\ngcn_layers: 1\ngclstm_layers: 1\n\n# LSTM units\nnum_hidden_units: 64\n# dense units\nnum_filter_conv1x1: 32\n\nbuild_transfer: False\n\n# merge parameters\ngraph_merge_gal_units: 64\ngraph_merge_gal_num_heads: 2\ntemporal_merge_gal_units: 64\ntemporal_merge_gal_num_heads: 2\n\nmodel_version: 'TMeta'"
  },
  {
    "path": "Experiments/STMeta/STMeta_v1.model.yml",
    "content": "# network structure parameters\r\nst_method: 'GCLSTM'\r\ntemporal_merge: 'gal'\r\ngraph_merge: 'gal'\r\n\r\n# gcn parameters\r\ngcn_k: 1\r\ngcn_layers: 1\r\ngclstm_layers: 1\r\n\r\n# LSTM units\r\nnum_hidden_units: 64\r\n# dense units\r\nnum_filter_conv1x1: 32\r\n\r\nbuild_transfer: False\r\n\r\n# merge parameters\r\ngraph_merge_gal_units: 64\r\ngraph_merge_gal_num_heads: 2\r\ntemporal_merge_gal_units: 64\r\ntemporal_merge_gal_num_heads: 2\r\n\r\nmodel_version: 'V1'"
  },
  {
    "path": "Experiments/STMeta/STMeta_v2.model.yml",
    "content": "# network structure parameters\r\nst_method: 'GCLSTM'\r\ntemporal_merge: 'concat'\r\ngraph_merge: 'gal'\r\n\r\n# gcn parameters\r\ngcn_k: 1\r\ngcn_layers: 1\r\ngclstm_layers: 1\r\n\r\n# LSTM units\r\nnum_hidden_units: 64\r\n# dense units\r\nnum_filter_conv1x1: 32\r\n\r\nbuild_transfer: False\r\n\r\n# merge parameters\r\ngraph_merge_gal_units: 64\r\ngraph_merge_gal_num_heads: 2\r\ntemporal_merge_gal_units: 64\r\ntemporal_merge_gal_num_heads: 2\r\n\r\nmodel_version: 'V2'"
  },
  {
    "path": "Experiments/STMeta/STMeta_v3.model.yml",
    "content": "# network structure parameters\r\nst_method: 'DCRNN'\r\ntemporal_merge: 'gal'\r\ngraph_merge: 'gal'\r\n\r\n# gcn parameters\r\ngcn_k: 1\r\ngcn_layers: 1\r\ngclstm_layers: 1\r\n\r\n# LSTM units\r\nnum_hidden_units: 64\r\n# dense units\r\nnum_filter_conv1x1: 32\r\n\r\n# temporal process params\r\ntemporal_gal_units: 32\r\ntemporal_gal_num_heads: 2\r\ntemporal_gal_layers: 4\r\n\r\nbuild_transfer: False\r\n\r\n# merge parameters\r\ngraph_merge_gal_units: 64\r\ngraph_merge_gal_num_heads: 2\r\ntemporal_merge_gal_units: 64\r\ntemporal_merge_gal_num_heads: 2\r\n\r\nmodel_version: 'V3'"
  },
  {
    "path": "Experiments/STMeta/bike_chicago.data.yml",
    "content": "# dataset and city\r\ndataset: Bike\r\ncity: Chicago\r\n\r\ncloseness_len: 6\r\nperiod_len: 7\r\ntrend_len: 4\r\nwith_tpe: False\r\n\r\ngraph: Distance-Correlation-Interaction\r\n\r\ndata_range: all\r\ntrain_data_length: '365'\r\n\r\nthreshold_distance: 1000\r\nthreshold_correlation: 0\r\nthreshold_interaction: 500\r\n\r\nnormalize: True\r\ntrain: True\r\n\r\nlr: 0.00001\r\nearly_stop_length: 100\r\nearly_stop_patience: 0.1\r\nmax_epoch: 20000\r\nbatch_size: 32\r\ntest_ratio: 0.1\r\nMergeWay: sum\r\n\r\ngroup: Chicago\r\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/bike_dc.data.yml",
    "content": "# dataset and city\ndataset: Bike\ncity: DC\n\ncloseness_len: 6\nperiod_len: 7\ntrend_len: 4\nwith_tpe: False\n\ngraph: Distance-Correlation-Interaction\n\ndata_range: all\ntrain_data_length: '365'\n\nthreshold_distance: 1000\nthreshold_correlation: 0\nthreshold_interaction: 500\n\nnormalize: True\ntrain: True\n\nlr: 0.00001\nearly_stop_length: 100\nearly_stop_patience: 0.1\nmax_epoch: 20000\nbatch_size: 32\ntest_ratio: 0.1\nMergeWay: sum\n\ngroup: DC\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/bike_nyc.data.yml",
    "content": "# dataset and city\r\ndataset: Bike\r\ncity: NYC\r\n\r\ncloseness_len: 6\r\nperiod_len: 7\r\ntrend_len: 4\r\nwith_tpe: False\r\n\r\ngraph: Distance-Correlation-Interaction\r\n\r\ndata_range: all\r\ntrain_data_length: '365'\r\n\r\nthreshold_distance: 1000\r\nthreshold_correlation: 0\r\nthreshold_interaction: 500\r\n\r\nnormalize: True\r\ntrain: True\r\n\r\nlr: 0.00001\r\nearly_stop_length: 100\r\nearly_stop_patience: 0.1\r\nmax_epoch: 20000\r\nbatch_size: 32\r\ntest_ratio: 0.1\r\nMergeWay: sum\r\n\r\ngroup: NYC\r\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/chargestation_beijing.data.yml",
    "content": "# dataset and city\r\ndataset: ChargeStation\r\ncity: Beijing\r\n\r\ncloseness_len: 6\r\nperiod_len: 7\r\ntrend_len: 4\r\nwith_tpe: False\r\n\r\ngraph: Correlation-Distance\r\n\r\ndata_range: all\r\ntrain_data_length: all\r\n\r\nthreshold_distance: 1000\r\nthreshold_correlation: 0.1\r\nthreshold_interaction: 500\r\n\r\nnormalize: True\r\ntrain: True\r\n\r\nlr: 1e-5\r\nearly_stop_length: 200\r\nearly_stop_patience: 0.1\r\nmax_epoch: 20000\r\nbatch_size: 64\r\ntest_ratio: 0.1\r\nMergeWay: max\r\n\r\ngroup: Beijing\r\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/didi_chengdu.data.yml",
    "content": "# dataset and city\ndataset: DiDi\ncity: Chengdu\n\ncloseness_len: 6\nperiod_len: 7\ntrend_len: 4\nwith_tpe: False\n\ngraph: Distance-Interaction-Correlation\n\ndata_range: all\ntrain_data_length: all\n\nthreshold_distance: 7500\nthreshold_correlation: 0.65\nthreshold_interaction: 30\n\nnormalize: True\ntrain: True\n\nlr: 1e-5\nearly_stop_length: 500\nearly_stop_patience: 0.1\nmax_epoch: 50000\nbatch_size: 32\ntest_ratio: 0.1\nMergeWay: sum\n\ngroup: Chengdu\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/didi_chengdu_street.data.yml",
    "content": "# dataset and city\ndataset: DiDi\ncity: Chengdu_Street\n\ncloseness_len: 6\nperiod_len: 7\ntrend_len: 4\nwith_tpe: False\n\ngraph: Distance-Interaction-Correlation\n\ndata_range: all\ntrain_data_length: all\n\nthreshold_distance: 7500\nthreshold_correlation: 0.65\nthreshold_interaction: 30\n\nnormalize: True\ntrain: True\n\nlr: 1e-5\nearly_stop_length: 500\nearly_stop_patience: 0.1\nmax_epoch: 50000\nbatch_size: 32\ntest_ratio: 0.1\nMergeWay: sum\n\ngroup: Chengdu_Street\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/didi_xian.data.yml",
    "content": "# dataset and city\r\ndataset: DiDi\r\ncity: Xian\r\n\r\ncloseness_len: 6\r\nperiod_len: 7\r\ntrend_len: 4\r\nwith_tpe: False\r\n\r\ngraph: Distance-Interaction-Correlation\r\n\r\ndata_range: all\r\ntrain_data_length: all\r\n\r\nthreshold_distance: 7500\r\nthreshold_correlation: 0.65\r\nthreshold_interaction: 30\r\n\r\nnormalize: True\r\ntrain: True\r\n\r\nlr: 1e-5\r\nearly_stop_length: 500\r\nearly_stop_patience: 0.1\r\nmax_epoch: 50000\r\nbatch_size: 64\r\ntest_ratio: 0.1\r\nMergeWay: sum\r\n\r\ngroup: Xian\r\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/didi_xian_street.data.yml",
    "content": "# dataset and city\ndataset: DiDi\ncity: Xian_Street\n\ncloseness_len: 6\nperiod_len: 7\ntrend_len: 4\nwith_tpe: False\n\ngraph: Distance-Interaction-Correlation\n\ndata_range: all\ntrain_data_length: all\n\nthreshold_distance: 7500\nthreshold_correlation: 0.65\nthreshold_interaction: 30\n\nnormalize: True\ntrain: True\n\nlr: 1e-5\nearly_stop_length: 500\nearly_stop_patience: 0.1\nmax_epoch: 50000\nbatch_size: 64\ntest_ratio: 0.1\nMergeWay: sum\n\ngroup: Xian_Street\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/gc_search.json",
    "content": "{\n    \"threshold_correlation\": {\"_type\":\"choice\",\"_value\":[0.65]},\n\n    \"gcn_k\": {\"_type\":\"choice\",\"_value\":[1, 2, 3]},\n\n    \"batch_size\": {\"_type\":\"choice\",\"_value\":[128]},\n\n    \"lr\": {\"_type\":\"choice\",\"_value\":[0.00002]},\n\n    \"gclstm_layers\": {\"_type\":\"choice\",\"_value\":[1]},\n\n    \"num_filter_conv1x1\": {\"_type\":\"choice\",\"_value\":[64]},\n\n    \"num_hidden_units\": {\"_type\":\"choice\",\"_value\":[64]},\n\n    \"temporal_merge_gal_units\": {\"_type\":\"choice\",\"_value\":[64]},\n\n    \"temporal_merge_gal_num_heads\": {\"_type\":\"choice\",\"_value\":[2]}\n}"
  },
  {
    "path": "Experiments/STMeta/lstm_search.json",
    "content": "{\r\n    \"threshold_correlation\": {\"_type\":\"choice\",\"_value\":[0.5, 0.55, 0.6, 0.65, 0.7]},\r\n\r\n    \"batch_size\": {\"_type\":\"choice\",\"_value\":[16, 32, 64, 128, 256]},\r\n\r\n    \"lr\": {\"_type\":\"choice\",\"_value\":[0.00001, 0.00002, 0.00004, 0.00008, 0.0001]},\r\n\r\n    \"gclstm_layers\": {\"_type\":\"choice\",\"_value\":[1, 2, 3]},\r\n\r\n    \"num_filter_conv1x1\": {\"_type\":\"choice\",\"_value\":[32, 64, 128]},\r\n\r\n    \"num_hidden_units\": {\"_type\":\"choice\",\"_value\":[32, 64, 128]},\r\n\r\n    \"temporal_merge_gal_units\": {\"_type\":\"choice\",\"_value\":[32, 64, 128]},\r\n\r\n    \"temporal_merge_gal_num_heads\": {\"_type\":\"choice\",\"_value\":[2, 3, 4]}\r\n}"
  },
  {
    "path": "Experiments/STMeta/metr_la.data.yml",
    "content": "# dataset and city\ndataset: METR\ncity: LA\n\ncloseness_len: 6\nperiod_len: 7\ntrend_len: 4\nwith_tpe: False\n\ngraph: Distance-Correlation\n\ndata_range: all\ntrain_data_length: all\n\nthreshold_distance: 5500\nthreshold_correlation: 0.73\nthreshold_interaction: 30\n\nnormalize: True\ntrain: True\n\nlr: 1e-5\nearly_stop_length: 400\nearly_stop_patience: 0.1\nmax_epoch: 10000\nbatch_size: 32\ntest_ratio: 0.2\nMergeWay: average\n\ngroup: LA\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/metro_chongqing.data.yml",
    "content": "# dataset and city\ndataset: Metro\ncity: Chongqing\n\ncloseness_len: 6\nperiod_len: 7\ntrend_len: 4\nwith_tpe: False\n\ngraph: Distance-Correlation-Line\n\ndata_range: all\ntrain_data_length: all\n\nthreshold_distance: 5000\nthreshold_correlation: 0.7\nthreshold_interaction: 30\n\nnormalize: True\ntrain: True\n\nlr: 1e-5\nearly_stop_length: 200\nearly_stop_patience: 0.1\nmax_epoch: 10000\nbatch_size: 64\ntest_ratio: 0.1\nMergeWay: sum\n\ngroup: Chongqing\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/metro_shanghai.data.yml",
    "content": "# dataset and city\ndataset: Metro\ncity: Shanghai\n\ncloseness_len: 6\nperiod_len: 7\ntrend_len: 4\nwith_tpe: False\n\ngraph: Distance-Correlation-Line\n\ndata_range: all\ntrain_data_length: all\n\nthreshold_distance: 5000\nthreshold_correlation: 0.7\nthreshold_interaction: 30\n\nnormalize: True\ntrain: True\n\nlr: 1e-5\nearly_stop_length: 200\nearly_stop_patience: 0.1\nmax_epoch: 20000\nbatch_size: 64\ntest_ratio: 0.1\nMergeWay: sum\n\ngroup: Shanghai\nmark: BM"
  },
  {
    "path": "Experiments/STMeta/param_search.yml",
    "content": "authorName: DiChai\r\nexperimentName: network_search\r\ntrialConcurrency: 1\r\nmaxExecDuration: 24h\r\nmaxTrialNum: 50\r\ntrainingServicePlatform: local\r\n# The path to Search Space\r\n#searchSpacePath: lstm_search.json\r\nsearchSpacePath: params_search.json\r\nuseAnnotation: false\r\ntuner:\r\n  builtinTunerName: TPE\r\n# The path and the running command of trial\r\ntrial:\r\n  command: python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml\r\n  codeDir: .\r\n  gpuNum: 1"
  },
  {
    "path": "Experiments/STMeta/pems_bay.data.yml",
    "content": "# dataset and city\ndataset: PEMS\ncity: BAY\n\ncloseness_len: 6\nperiod_len: 7\ntrend_len: 4\nwith_tpe: False\n\ngraph: Distance-Correlation\n\ndata_range: all\ntrain_data_length: all\n\nthreshold_distance: 5500\nthreshold_correlation: 0.63\nthreshold_interaction: 30\n\nnormalize: True\ntrain: True\n\nlr: 1e-5\nearly_stop_length: 400\nearly_stop_patience: 0.1\nmax_epoch: 10000\nbatch_size: 32\ntest_ratio: 0.2\nMergeWay: average\n\ngroup: BAY\nmark: BM"
  },
  {
    "path": "Experiments/STMeta_Transfer/Runner.py",
    "content": "import os\n\n# os.system('python STMeta_Transfer_Test.py --source_data bike_nyc.data.yml --target_data bike_chicago.data.yml '\n#           '--target_data_length 1 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_nyc.data.yml --target_data bike_chicago.data.yml '\n#           '--target_data_length 3 --transfer_ratio 0.1 --similarity_mode checkin')\nos.system('python STMeta_Transfer_Test.py --source_data bike_nyc.data.yml --target_data bike_chicago.data.yml '\n          '--target_data_length 5 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_nyc.data.yml --target_data bike_chicago.data.yml '\n#           '--target_data_length 7 --transfer_ratio 0.1 --similarity_mode checkin')\n\n#####################################################################################################################\n\n# os.system('python STMeta_Transfer_Test.py --source_data bike_nyc.data.yml --target_data bike_dc.data.yml '\n#           '--target_data_length 1 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_nyc.data.yml --target_data bike_dc.data.yml '\n#           '--target_data_length 3 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_nyc.data.yml --target_data bike_dc.data.yml '\n#           '--target_data_length 5 --transfer_ratio 0.1 --similarity_mode checkin')\nos.system('python STMeta_Transfer_Test.py --source_data bike_nyc.data.yml --target_data bike_dc.data.yml '\n          '--target_data_length 7 --transfer_ratio 0.1 --similarity_mode checkin')\n\n#####################################################################################################################\n\n# os.system('python STMeta_Transfer_Test.py --source_data bike_chicago.data.yml --target_data bike_dc.data.yml '\n#           '--target_data_length 1 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_chicago.data.yml --target_data bike_dc.data.yml '\n#           '--target_data_length 3 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_chicago.data.yml --target_data bike_dc.data.yml '\n#           '--target_data_length 5 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_chicago.data.yml --target_data bike_dc.data.yml '\n#           '--target_data_length 7 --transfer_ratio 0.1 --similarity_mode checkin')\n#####################################################################################################################\n\nos.system('python STMeta_Transfer_Test.py --source_data bike_chicago.data.yml --target_data bike_nyc.data.yml '\n          '--target_data_length 1 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_chicago.data.yml --target_data bike_nyc.data.yml '\n#           '--target_data_length 3 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_chicago.data.yml --target_data bike_nyc.data.yml '\n#           '--target_data_length 5 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_chicago.data.yml --target_data bike_nyc.data.yml '\n#           '--target_data_length 7 --transfer_ratio 0.1 --similarity_mode checkin')\n\n####################################################################################################################\n\n# os.system('python STMeta_Transfer_Test.py --source_data bike_dc.data.yml --target_data bike_nyc.data.yml '\n#           '--target_data_length 1 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_dc.data.yml --target_data bike_nyc.data.yml '\n#           '--target_data_length 3 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_dc.data.yml --target_data bike_nyc.data.yml '\n#           '--target_data_length 5 --transfer_ratio 0.1 --similarity_mode checkin')\nos.system('python STMeta_Transfer_Test.py --source_data bike_dc.data.yml --target_data bike_nyc.data.yml '\n          '--target_data_length 7 --transfer_ratio 0.1 --similarity_mode checkin')\n\n#####################################################################################################################\n\n# os.system('python STMeta_Transfer_Test.py --source_data bike_dc.data.yml --target_data bike_chicago.data.yml '\n#           '--target_data_length 1 --transfer_ratio 0.1 --similarity_mode checkin')\nos.system('python STMeta_Transfer_Test.py --source_data bike_dc.data.yml --target_data bike_chicago.data.yml '\n          '--target_data_length 3 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_dc.data.yml --target_data bike_chicago.data.yml '\n#           '--target_data_length 5 --transfer_ratio 0.1 --similarity_mode checkin')\n# os.system('python STMeta_Transfer_Test.py --source_data bike_dc.data.yml --target_data bike_chicago.data.yml '\n#           '--target_data_length 7 --transfer_ratio 0.1 --similarity_mode checkin')"
  },
  {
    "path": "Experiments/STMeta_Transfer/STMeta_Pretrain.py",
    "content": "import os\nimport yaml\nimport argparse\nimport GPUtil\nimport numpy as np\n\nfrom UCTB.dataset import TransferDataLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\n\n#####################################################################\n# argument parser\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\nparser.add_argument('-m', '--model', default='STMeta_v4.model.yml')\nparser.add_argument('-sd', '--source_data', default='bike_dc.data.yml')\nparser.add_argument('-td', '--target_data', default='bike_dc.data.yml')\nparser.add_argument('-tdl', '--target_data_length', default='365', type=str)\nparser.add_argument('-pt', '--pretrain', default='True')\nparser.add_argument('-ft', '--finetune', default='True')\nparser.add_argument('-tr', '--transfer', default='True')\n\nargs = vars(parser.parse_args())\n\nwith open(args['model'], 'r') as f:\n    model_params = yaml.load(f)\n\nwith open(args['source_data'], 'r') as f:\n    sd_params = yaml.load(f)\n\nwith open(args['target_data'], 'r') as f:\n    td_params = yaml.load(f)\n\nassert sd_params['closeness_len'] == td_params['closeness_len']\nassert sd_params['period_len'] == td_params['period_len']\nassert sd_params['trend_len'] == td_params['trend_len']\n\n\ndef show_prediction(pretrain, finetune, transfer, target, station_index, start=0, end=-1):\n\n    import matplotlib.pyplot as plt\n\n    fig, axs = plt.subplots()\n\n    axs.plot(pretrain[start:end, station_index], 'b', label='pretrain')\n    axs.plot(finetune[start:end, station_index], 'g', label='finetune')\n    axs.plot(transfer[start:end, station_index], 'y', label='transfer')\n    axs.plot(target[start:end, station_index], 'r', label='target')\n\n    axs.grid()\n    axs.legend(fontsize=15)\n\n    axs.set_xlabel('Time', fontsize=15)\n    axs.set_ylabel('Demand', fontsize=15)\n\n    axs.set_title('Station/Grid %s' % station_index)\n\n    fig.set_size_inches(10, 5)\n    fig.savefig(os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'PNG'),\n                             '%s.png' % 'station-%s' % station_index), dpi=150)\n    plt.close()\n\n#####################################################################\n# Generate code_version\ngroup = 'STMeta_Transfer'\ncode_version = 'STMeta_SD_{}_TD_{}'.format(args['source_data'].split('.')[0].split('_')[-1],\n                                                 args['target_data'].split('.')[0].split('_')[-1])\n\nsub_code_version = 'C{}P{}T{}_G{}_TP'.format(sd_params['closeness_len'], sd_params['period_len'], sd_params['trend_len'],\n                                             ''.join([e[0].upper() for e in sd_params['graph'].split('-')]))\n\nmodel_dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'model_dir')\nmodel_dir_path = os.path.join(model_dir_path, group)\n#####################################################################\n# Config data loader\n\ndata_loader = TransferDataLoader(sd_params, td_params, model_params, td_data_length=args['target_data_length'])\n\ndeviceIDs = GPUtil.getAvailable(order='memory', limit=2, maxLoad=1, maxMemory=1,\n                                includeNan=False, excludeID=[], excludeUUID=[])\n\nif len(deviceIDs) == 0:\n    current_device = '-1'\nelse:\n    current_device = str(deviceIDs[0])\n\nsd_model = STMeta(num_node=data_loader.sd_loader.station_number,\n                  num_graph=data_loader.sd_loader.LM.shape[0],\n                  external_dim=data_loader.sd_loader.external_dim,\n                  tpe_dim=data_loader.sd_loader.tpe_dim,\n                  code_version=code_version,\n                  model_dir=model_dir_path,\n                  gpu_device=current_device,\n                  transfer_ratio=0,\n                  **sd_params, **model_params)\nsd_model.build()\n\ntd_model = STMeta(num_node=data_loader.td_loader.station_number,\n                  num_graph=data_loader.td_loader.LM.shape[0],\n                  external_dim=data_loader.td_loader.external_dim,\n                  tpe_dim=data_loader.td_loader.tpe_dim,\n                  code_version=code_version,\n                  model_dir=model_dir_path,\n                  transfer_ratio=0.1,\n                  gpu_device=current_device,\n                  **td_params, **model_params)\ntd_model.build()\n\nsd_de_normalizer = (lambda x: x) if sd_params['normalize'] is False \\\n                                else data_loader.sd_loader.normalizer.min_max_denormal\ntd_de_normalizer = (lambda x: x) if td_params['normalize'] is False \\\n                                else data_loader.td_loader.normalizer.min_max_denormal\n\nprint('#################################################################')\nprint('Source Domain information')\nprint(sd_params['dataset'], sd_params['city'])\nprint('Number of trainable variables', sd_model.trainable_vars)\nprint('Number of training samples', data_loader.sd_loader.train_sequence_len)\n\nprint('#################################################################')\nprint('Target Domain information')\nprint(td_params['dataset'], td_params['city'])\nprint('Number of trainable variables', td_model.trainable_vars)\nprint('Number of training samples', data_loader.td_loader.train_sequence_len)\n\npretrain_model_name = 'Pretrain_' + sub_code_version\nfinetune_model_name = 'Finetune_' + sub_code_version + '_' + str(data_loader.td_loader.train_sequence_len)\ntransfer_model_name = 'Transfer_' + sub_code_version + '_' + str(data_loader.td_loader.train_sequence_len)\n\nif args['pretrain'] == 'True':\n\n    try:\n        td_model.load(pretrain_model_name)\n\n    except FileNotFoundError:\n\n        traffic_sim = data_loader.traffic_sim_fake()\n\n        # prepare data:\n        feature_maps = []\n        for record in traffic_sim:\n            # score, index, start, end\n            # sd_transfer_data = data_loader.sd_loader.train_data[record[2]: record[3], :]\n            sd_transfer_data = data_loader.sd_loader.train_data[-data_loader.td_loader.train_data.shape[0]:, :]\n\n            transfer_closeness, \\\n            transfer_period, \\\n            transfer_trend, \\\n            _ = data_loader.sd_loader.st_move_sample.move_sample(sd_transfer_data)\n\n            fm = sd_model.predict(closeness_feature=transfer_closeness,\n                                  period_feature=transfer_period,\n                                  trend_feature=transfer_trend,\n                                  laplace_matrix=data_loader.sd_loader.LM,\n                                  external_feature=data_loader.sd_loader.train_ef,\n                                  output_names=['feature_map'],\n                                  sequence_length=len(transfer_closeness),\n                                  cache_volume=sd_params['batch_size'])\n\n            feature_maps.append(fm['feature_map'][:, record[1]:record[1] + 1, :, :])\n\n        feature_maps = np.concatenate(feature_maps, axis=1)\n\n        # transfer\n        td_model.fit(closeness_feature=data_loader.td_loader.train_closeness,\n                     period_feature=data_loader.td_loader.train_period,\n                     trend_feature=data_loader.td_loader.train_trend,\n                     laplace_matrix=data_loader.td_loader.LM,\n                     target=data_loader.td_loader.train_y,\n                     external_feature=data_loader.td_loader.train_ef,\n                     similar_feature_map=feature_maps,\n                     sequence_length=data_loader.td_loader.train_sequence_len,\n                     output_names=('transfer_loss',),\n                     evaluate_loss_name='transfer_loss',\n                     op_names=('transfer_op',),\n                     batch_size=td_params['batch_size'],\n                     max_epoch=td_params['max_epoch'],\n                     validate_ratio=0.1,\n                     early_stop_method='t-test',\n                     early_stop_length=td_params['early_stop_length'],\n                     early_stop_patience=td_params['early_stop_patience'],\n                     verbose=True,\n                     save_model=True)\n        td_model.save(pretrain_model_name, global_step=0)\n\n    prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                  period_feature=data_loader.td_loader.test_period,\n                                  trend_feature=data_loader.td_loader.test_trend,\n                                  laplace_matrix=data_loader.td_loader.LM,\n                                  target=data_loader.td_loader.test_y,\n                                  external_feature=data_loader.td_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.td_loader.test_sequence_len,\n                                  cache_volume=td_params['batch_size'], )\n\n    transfer_prediction = prediction['prediction']\n\n    test_rmse, test_mape = metric.rmse(prediction=td_de_normalizer(transfer_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y)), \\\n                           metric.mape(prediction=td_de_normalizer(transfer_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Target Domain Transfer')\n    print(test_rmse, test_mape)"
  },
  {
    "path": "Experiments/STMeta_Transfer/STMeta_Transfer.py",
    "content": "import os\nimport yaml\nimport argparse\nimport GPUtil\nimport numpy as np\n\nfrom UCTB.dataset import TransferDataLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\n\n#####################################################################\n# argument parser\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\nparser.add_argument('-m', '--model', default='STMeta_v4.model.yml')\nparser.add_argument('-sd', '--source_data', default='bike_nyc.data.yml')\nparser.add_argument('-td', '--target_data', default='bike_chicago.data.yml')\nparser.add_argument('-tdl', '--target_data_length', default='3', type=str)\nparser.add_argument('-tfr', '--transfer_ratio', default='0.1', type=str)\nparser.add_argument('-pt', '--pretrain', default='True')\nparser.add_argument('-ft', '--finetune', default='True')\nparser.add_argument('-tr', '--transfer', default='True')\n\nargs = vars(parser.parse_args())\n\nwith open(args['model'].strip('./\\\\'), 'r') as f:\n    model_params = yaml.load(f)\n\nwith open(args['source_data'].strip('./\\\\'), 'r') as f:\n    sd_params = yaml.load(f)\n\nwith open(args['target_data'].strip('./\\\\'), 'r') as f:\n    td_params = yaml.load(f)\n\nassert sd_params['closeness_len'] == td_params['closeness_len']\nassert sd_params['period_len'] == td_params['period_len']\nassert sd_params['trend_len'] == td_params['trend_len']\n\n\ndef show_prediction(pretrain, finetune, transfer, target, station_index, start=0, end=-1):\n\n    import matplotlib.pyplot as plt\n\n    fig, axs = plt.subplots()\n\n    axs.plot(pretrain[start:end, station_index], 'b', label='pretrain')\n    axs.plot(finetune[start:end, station_index], 'g', label='finetune')\n    axs.plot(transfer[start:end, station_index], 'y', label='transfer')\n    axs.plot(target[start:end, station_index], 'r', label='target')\n\n    axs.grid()\n    axs.legend(fontsize=15)\n\n    axs.set_xlabel('Time', fontsize=15)\n    axs.set_ylabel('Demand', fontsize=15)\n\n    axs.set_title('Station/Grid %s' % station_index)\n\n    fig.set_size_inches(10, 5)\n    fig.savefig(os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'PNG'),\n                             '%s.png' % 'station-%s' % station_index), dpi=150)\n    plt.close()\n\n#####################################################################\n# Generate code_version\ngroup = 'STMeta_Transfer'\ncode_version = 'STMeta_SD_{}_TD_{}'.format(args['source_data'].split('.')[0].split('_')[-1],\n                                                 args['target_data'].split('.')[0].split('_')[-1])\n\nsub_code_version = 'C{}P{}T{}_G{}'.format(sd_params['closeness_len'], sd_params['period_len'], sd_params['trend_len'],\n                                          ''.join([e[0].upper() for e in sd_params['graph'].split('-')]))\n\nmodel_dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'model_dir')\nmodel_dir_path = os.path.join(model_dir_path, group)\n#####################################################################\n# Config data loader\n\ndata_loader = TransferDataLoader(sd_params, td_params, model_params, td_data_length=args['target_data_length'])\n\ndeviceIDs = GPUtil.getAvailable(order='memory', limit=2, maxLoad=1, maxMemory=1,\n                                includeNan=False, excludeID=[], excludeUUID=[])\n\nif len(deviceIDs) == 0:\n    current_device = '-1'\nelse:\n    current_device = str(deviceIDs[0])\n\nsd_model = STMeta(num_node=data_loader.sd_loader.station_number,\n                  num_graph=data_loader.sd_loader.LM.shape[0],\n                  external_dim=data_loader.sd_loader.external_dim,\n                  tpe_dim=data_loader.sd_loader.tpe_dim,\n                  code_version=code_version,\n                  model_dir=model_dir_path,\n                  gpu_device=current_device,\n                  transfer_ratio=0,\n                  **sd_params, **model_params)\nsd_model.build(init_vars=True)\n\ntransfer_ratio = float(args['transfer_ratio'])\n\ntd_model = STMeta(num_node=data_loader.td_loader.station_number,\n                  num_graph=data_loader.td_loader.LM.shape[0],\n                  external_dim=data_loader.td_loader.external_dim,\n                  tpe_dim=data_loader.td_loader.tpe_dim,\n                  code_version=code_version,\n                  model_dir=model_dir_path,\n                  transfer_ratio=transfer_ratio,\n                  gpu_device=current_device,\n                  **td_params, **model_params)\n\ntd_model.build(init_vars=False, max_to_keep=None)\n\nsd_de_normalizer = (lambda x: x) if sd_params['normalize'] is False \\\n                                else data_loader.sd_loader.normalizer.min_max_denormal\ntd_de_normalizer = (lambda x: x) if td_params['normalize'] is False \\\n                                else data_loader.td_loader.normalizer.min_max_denormal\n\nprint('#################################################################')\nprint('Source Domain information')\nprint(sd_params['dataset'], sd_params['city'])\nprint('Number of trainable variables', sd_model.trainable_vars)\nprint('Number of training samples', data_loader.sd_loader.train_sequence_len)\n\nprint('#################################################################')\nprint('Target Domain information')\nprint(td_params['dataset'], td_params['city'])\nprint('Number of trainable variables', td_model.trainable_vars)\nprint('Number of training samples', data_loader.td_loader.train_sequence_len)\n\npretrain_model_name = 'Pretrain_' + sub_code_version\nfinetune_model_name = 'Finetune_' + sub_code_version + '_' + str(data_loader.td_loader.train_sequence_len)\ntransfer_model_name = 'Transfer_' + sub_code_version + '_' + str(data_loader.td_loader.train_sequence_len) +\\\n                      '_%s' % int((transfer_ratio * 100)) + '%'\n\nwriting_obj = [''.join([e for e in sd_params['graph'].split('-')]),\n               args['source_data'].split('.')[0].split('_')[-1],\n               args['target_data'].split('.')[0].split('_')[-1],\n               str(transfer_ratio), '%s天' % args['target_data_length']]\n\nif args['pretrain'] == 'True':\n    try:\n        sd_model.load(pretrain_model_name)\n    except FileNotFoundError:\n        sd_model.fit(closeness_feature=data_loader.sd_loader.train_closeness,\n                     period_feature=data_loader.sd_loader.train_period,\n                     trend_feature=data_loader.sd_loader.train_trend,\n                     laplace_matrix=data_loader.sd_loader.LM,\n                     target=data_loader.sd_loader.train_y,\n                     external_feature=data_loader.sd_loader.train_ef,\n                     sequence_length=data_loader.sd_loader.train_sequence_len,\n                     output_names=('loss',),\n                     evaluate_loss_name='loss',\n                     op_names=('train_op',),\n                     batch_size=sd_params['batch_size'],\n                     max_epoch=sd_params['max_epoch'],\n                     validate_ratio=0.1,\n                     early_stop_method='t-test',\n                     early_stop_length=sd_params['early_stop_length'],\n                     early_stop_patience=sd_params['early_stop_patience'],\n                     verbose=True,\n                     save_model=True)\n        sd_model.save(pretrain_model_name, global_step=0)\n\n    sd_model.load(pretrain_model_name)\n\n    prediction = sd_model.predict(closeness_feature=data_loader.sd_loader.test_closeness,\n                                  period_feature=data_loader.sd_loader.test_period,\n                                  trend_feature=data_loader.sd_loader.test_trend,\n                                  laplace_matrix=data_loader.sd_loader.LM,\n                                  target=data_loader.sd_loader.test_y,\n                                  external_feature=data_loader.sd_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.sd_loader.test_sequence_len,\n                                  cache_volume=sd_params['batch_size'], )\n\n    test_prediction = prediction['prediction']\n\n    test_rmse, test_mape = metric.rmse(prediction=sd_de_normalizer(test_prediction),\n                                       target=sd_de_normalizer(data_loader.sd_loader.test_y)), \\\n                           metric.mape(prediction=sd_de_normalizer(test_prediction),\n                                       target=sd_de_normalizer(data_loader.sd_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Source Domain Result')\n    print(test_rmse, test_mape)\n\n    td_model.load(pretrain_model_name)\n\n    prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                  period_feature=data_loader.td_loader.test_period,\n                                  trend_feature=data_loader.td_loader.test_trend,\n                                  laplace_matrix=data_loader.td_loader.LM,\n                                  target=data_loader.td_loader.test_y,\n                                  external_feature=data_loader.td_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.td_loader.test_sequence_len,\n                                  cache_volume=td_params['batch_size'], )\n\n    pretrain_prediction = prediction['prediction']\n\n    test_rmse, test_mape = metric.rmse(prediction=td_de_normalizer(pretrain_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y)), \\\n                           metric.mape(prediction=td_de_normalizer(pretrain_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Target Domain Result')\n    print(test_rmse, test_mape)\n    writing_obj.append('%.5f' % test_rmse)\n\nif args['finetune'] == 'True':\n    try:\n        td_model.load(finetune_model_name)\n    except FileNotFoundError:\n        td_model.load(pretrain_model_name)\n        td_model.fit(closeness_feature=data_loader.td_loader.train_closeness,\n                     period_feature=data_loader.td_loader.train_period,\n                     trend_feature=data_loader.td_loader.train_trend,\n                     laplace_matrix=data_loader.td_loader.LM,\n                     target=data_loader.td_loader.train_y,\n                     external_feature=data_loader.td_loader.train_ef,\n                     sequence_length=data_loader.td_loader.train_sequence_len,\n                     output_names=('loss',),\n                     evaluate_loss_name='loss',\n                     op_names=('train_op',),\n                     batch_size=td_params['batch_size'],\n                     max_epoch=td_params['max_epoch'],\n                     validate_ratio=0.3,\n                     early_stop_method='t-test',\n                     early_stop_length=td_params['early_stop_length'],\n                     early_stop_patience=td_params['early_stop_patience'],\n                     verbose=True,\n                     save_model=True,\n                     save_model_name=finetune_model_name,\n                     auto_load_model=False)\n\n    td_model.load(finetune_model_name)\n\n    prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                  period_feature=data_loader.td_loader.test_period,\n                                  trend_feature=data_loader.td_loader.test_trend,\n                                  laplace_matrix=data_loader.td_loader.LM,\n                                  target=data_loader.td_loader.test_y,\n                                  external_feature=data_loader.td_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.td_loader.test_sequence_len,\n                                  cache_volume=td_params['batch_size'], )\n\n    finetune_prediction = prediction['prediction']\n\n    finetune_error_station = np.array([metric.rmse(td_de_normalizer(finetune_prediction[:, i]),\n                                                   td_de_normalizer(data_loader.td_loader.test_y[:, i]))\n                                                   for i in range(len(finetune_prediction[0]))])\n\n    test_rmse, test_mape = metric.rmse(prediction=td_de_normalizer(finetune_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y)), \\\n                           metric.mape(prediction=td_de_normalizer(finetune_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Target Domain Fine-tune')\n    print(test_rmse, test_mape)\n    writing_obj.append('%.5f' % test_rmse)\n\nif args['transfer'] == 'True':\n\n    try:\n        td_model.load(transfer_model_name)\n    except FileNotFoundError:\n        traffic_sim = data_loader.checkin_sim()\n\n        sd_model.load(pretrain_model_name)\n\n        sd_transfer_data = data_loader.sd_loader.train_data[-data_loader.td_loader.train_data.shape[0]:, :]\n\n        transfer_closeness, \\\n        transfer_period, \\\n        transfer_trend, \\\n        _ = data_loader.sd_loader.st_move_sample.move_sample(sd_transfer_data)\n\n        fm = sd_model.predict(closeness_feature=transfer_closeness,\n                              period_feature=transfer_period,\n                              trend_feature=transfer_trend,\n                              laplace_matrix=data_loader.sd_loader.LM,\n                              external_feature=data_loader.sd_loader.train_ef,\n                              output_names=['feature_map'],\n                              sequence_length=len(transfer_closeness),\n                              cache_volume=sd_params['batch_size'])\n\n        feature_maps = np.take(fm['feature_map'], np.array([e[1] for e in traffic_sim]), axis=1)\n\n        # transfer\n        td_model.load(pretrain_model_name)\n        td_model.fit(closeness_feature=data_loader.td_loader.train_closeness,\n                     period_feature=data_loader.td_loader.train_period,\n                     trend_feature=data_loader.td_loader.train_trend,\n                     laplace_matrix=data_loader.td_loader.LM,\n                     target=data_loader.td_loader.train_y,\n                     external_feature=data_loader.td_loader.train_ef,\n                     similar_feature_map=feature_maps,\n                     sequence_length=data_loader.td_loader.train_sequence_len,\n                     output_names=('transfer_loss', 'loss'),\n                     evaluate_loss_name='loss',\n                     op_names=('transfer_op',),\n                     batch_size=td_params['batch_size'],\n                     max_epoch=td_params['max_epoch'],\n                     validate_ratio=0.3,\n                     early_stop_method='t-test',\n                     early_stop_length=td_params['early_stop_length'],\n                     early_stop_patience=td_params['early_stop_patience'],\n                     verbose=True,\n                     save_model=True,\n                     save_model_name=transfer_model_name,\n                     auto_load_model=False)\n\n    td_model.load(transfer_model_name)\n\n    prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                  period_feature=data_loader.td_loader.test_period,\n                                  trend_feature=data_loader.td_loader.test_trend,\n                                  laplace_matrix=data_loader.td_loader.LM,\n                                  target=data_loader.td_loader.test_y,\n                                  external_feature=data_loader.td_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.td_loader.test_sequence_len,\n                                  cache_volume=td_params['batch_size'], )\n\n    transfer_prediction = prediction['prediction']\n\n    transfer_error_station = np.array([metric.rmse(td_de_normalizer(transfer_prediction[:, i]),\n                                                   td_de_normalizer(data_loader.td_loader.test_y[:, i]))\n                                       for i in range(len(transfer_prediction[0]))])\n\n    test_rmse, test_mape = metric.rmse(prediction=td_de_normalizer(transfer_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y)), \\\n                           metric.mape(prediction=td_de_normalizer(transfer_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Target Domain Transfer')\n    print(test_rmse, test_mape)\n    writing_obj.append('%.5f' % test_rmse)\n\nwith open('transfer_record.md', 'a+', encoding='utf-8') as f:\n    f.write('|' + '|'.join(writing_obj) + '|' + '\\n')\n\n# Plot\n# data_loader.td_loader.st_map(build_order=finetune_error_station-transfer_error_station)\n\n# for index in range(0, data_loader.td_loader.station_number, 10):\n#\n#     show_prediction(pretrain=pretrain_prediction,\n#                     finetune=finetune_prediction,\n#                     transfer=transfer_prediction,\n#                     target=data_loader.td_loader.test_y,\n#                     station_index=index, start=0, end=500)"
  },
  {
    "path": "Experiments/STMeta_Transfer/STMeta_Transfer_Dynamic.py",
    "content": "import os\nimport yaml\nimport argparse\nimport GPUtil\nimport numpy as np\n\nfrom UCTB.dataset import TransferDataLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\nfrom UCTB.train import EarlyStoppingTTest\n\n#####################################################################\n# argument parser\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\nparser.add_argument('-m', '--model', default='STMeta_v4.model.yml')\nparser.add_argument('-sd', '--source_data', default='bike_nyc.data.yml')\nparser.add_argument('-td', '--target_data', default='bike_dc.data.yml')\nparser.add_argument('-tdl', '--target_data_length', default='1', type=str)\nparser.add_argument('-tfr', '--transfer_ratio', default='0.1', type=str)\nparser.add_argument('-pt', '--pretrain', default='True')\nparser.add_argument('-ft', '--finetune', default='True')\nparser.add_argument('-tr', '--transfer', default='True')\n\nargs = vars(parser.parse_args())\n\nwith open(args['model'].strip('./\\\\'), 'r') as f:\n    model_params = yaml.load(f)\n\nwith open(args['source_data'].strip('./\\\\'), 'r') as f:\n    sd_params = yaml.load(f)\n\nwith open(args['target_data'].strip('./\\\\'), 'r') as f:\n    td_params = yaml.load(f)\n\nassert sd_params['closeness_len'] == td_params['closeness_len']\nassert sd_params['period_len'] == td_params['period_len']\nassert sd_params['trend_len'] == td_params['trend_len']\n\n\ndef show_prediction(pretrain, finetune, transfer, target, station_index, start=0, end=-1):\n\n    import matplotlib.pyplot as plt\n\n    fig, axs = plt.subplots()\n\n    axs.plot(pretrain[start:end, station_index], 'b', label='pretrain')\n    axs.plot(finetune[start:end, station_index], 'g', label='finetune')\n    axs.plot(transfer[start:end, station_index], 'y', label='transfer')\n    axs.plot(target[start:end, station_index], 'r', label='target')\n\n    axs.grid()\n    axs.legend(fontsize=15)\n\n    axs.set_xlabel('Time', fontsize=15)\n    axs.set_ylabel('Demand', fontsize=15)\n\n    axs.set_title('Station/Grid %s' % station_index)\n\n    fig.set_size_inches(10, 5)\n    fig.savefig(os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'PNG'),\n                             '%s.png' % 'station-%s' % station_index), dpi=150)\n    plt.close()\n\n#####################################################################\n# Generate code_version\ngroup = 'STMeta_Transfer'\ncode_version = 'STMeta_SD_{}_TD_{}'.format(args['source_data'].split('.')[0].split('_')[-1],\n                                                 args['target_data'].split('.')[0].split('_')[-1])\n\nsub_code_version = 'C{}P{}T{}_G{}'.format(sd_params['closeness_len'], sd_params['period_len'], sd_params['trend_len'],\n                                          ''.join([e[0].upper() for e in sd_params['graph'].split('-')]))\n\nmodel_dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'model_dir')\nmodel_dir_path = os.path.join(model_dir_path, group)\n#####################################################################\n# Config data loader\n\ndata_loader = TransferDataLoader(sd_params, td_params, model_params, td_data_length=args['target_data_length'])\n\ndeviceIDs = GPUtil.getAvailable(order='memory', limit=2, maxLoad=1, maxMemory=1,\n                                includeNan=False, excludeID=[], excludeUUID=[])\n\nif len(deviceIDs) == 0:\n    current_device = '-1'\nelse:\n    current_device = str(deviceIDs[0])\n\nsd_model = STMeta(num_node=data_loader.sd_loader.station_number,\n                  num_graph=data_loader.sd_loader.LM.shape[0],\n                  external_dim=data_loader.sd_loader.external_dim,\n                  tpe_dim=data_loader.sd_loader.tpe_dim,\n                  code_version=code_version,\n                  model_dir=model_dir_path,\n                  gpu_device=current_device,\n                  transfer_ratio=0,\n                  **sd_params, **model_params)\nsd_model.build(init_vars=True)\n\ntransfer_ratio = float(args['transfer_ratio'])\n\ntd_model = STMeta(num_node=data_loader.td_loader.station_number,\n                  num_graph=data_loader.td_loader.LM.shape[0],\n                  external_dim=data_loader.td_loader.external_dim,\n                  tpe_dim=data_loader.td_loader.tpe_dim,\n                  code_version=code_version,\n                  model_dir=model_dir_path,\n                  transfer_ratio=transfer_ratio,\n                  gpu_device=current_device,\n                  **td_params, **model_params)\n\ntd_model.build(init_vars=False, max_to_keep=None)\n\nsd_de_normalizer = (lambda x: x) if sd_params['normalize'] is False \\\n                                else data_loader.sd_loader.normalizer.min_max_denormal\ntd_de_normalizer = (lambda x: x) if td_params['normalize'] is False \\\n                                else data_loader.td_loader.normalizer.min_max_denormal\n\nprint('#################################################################')\nprint('Source Domain information')\nprint(sd_params['dataset'], sd_params['city'])\nprint('Number of trainable variables', sd_model.trainable_vars)\nprint('Number of training samples', data_loader.sd_loader.train_sequence_len)\n\nprint('#################################################################')\nprint('Target Domain information')\nprint(td_params['dataset'], td_params['city'])\nprint('Number of trainable variables', td_model.trainable_vars)\nprint('Number of training samples', data_loader.td_loader.train_sequence_len)\n\npretrain_model_name = 'Pretrain_' + sub_code_version\nfinetune_model_name = 'Finetune_' + sub_code_version + '_' + str(data_loader.td_loader.train_sequence_len)\ntransfer_model_name = 'Transfer_' + sub_code_version + '_' + str(data_loader.td_loader.train_sequence_len) +\\\n                      '_%s' % int((transfer_ratio * 100)) + '%'\n\nwriting_obj = [args['source_data'].split('.')[0].split('_')[-1],\n               args['target_data'].split('.')[0].split('_')[-1],\n               str(transfer_ratio), '%s天' % args['target_data_length']]\n\nrmse_threshold = 0\n\nif args['pretrain'] == 'True':\n    print('#################################################################')\n    print('Source Domain Pre-Train')\n\n    try:\n        sd_model.load(pretrain_model_name)\n    except FileNotFoundError:\n        sd_model.fit(closeness_feature=data_loader.sd_loader.train_closeness,\n                     period_feature=data_loader.sd_loader.train_period,\n                     trend_feature=data_loader.sd_loader.train_trend,\n                     laplace_matrix=data_loader.sd_loader.LM,\n                     target=data_loader.sd_loader.train_y,\n                     external_feature=data_loader.sd_loader.train_ef,\n                     sequence_length=data_loader.sd_loader.train_sequence_len,\n                     output_names=('loss',),\n                     evaluate_loss_name='loss',\n                     op_names=('train_op',),\n                     batch_size=sd_params['batch_size'],\n                     max_epoch=sd_params['max_epoch'],\n                     validate_ratio=0.1,\n                     early_stop_method='t-test',\n                     early_stop_length=sd_params['early_stop_length'],\n                     early_stop_patience=sd_params['early_stop_patience'],\n                     verbose=True,\n                     save_model=True)\n        sd_model.save(pretrain_model_name, global_step=0)\n\n    sd_model.load(pretrain_model_name)\n\n    prediction = sd_model.predict(closeness_feature=data_loader.sd_loader.test_closeness,\n                                  period_feature=data_loader.sd_loader.test_period,\n                                  trend_feature=data_loader.sd_loader.test_trend,\n                                  laplace_matrix=data_loader.sd_loader.LM,\n                                  target=data_loader.sd_loader.test_y,\n                                  external_feature=data_loader.sd_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.sd_loader.test_sequence_len,\n                                  cache_volume=sd_params['batch_size'], )\n\n    test_prediction = prediction['prediction']\n\n    test_rmse, test_mape = metric.rmse(prediction=sd_de_normalizer(test_prediction),\n                                       target=sd_de_normalizer(data_loader.sd_loader.test_y)), \\\n                           metric.mape(prediction=sd_de_normalizer(test_prediction),\n                                       target=sd_de_normalizer(data_loader.sd_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Source Domain Result')\n    print(test_rmse, test_mape)\n\n    td_model.load(pretrain_model_name)\n\n    prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                  period_feature=data_loader.td_loader.test_period,\n                                  trend_feature=data_loader.td_loader.test_trend,\n                                  laplace_matrix=data_loader.td_loader.LM,\n                                  target=data_loader.td_loader.test_y,\n                                  external_feature=data_loader.td_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.td_loader.test_sequence_len,\n                                  cache_volume=td_params['batch_size'], )\n\n    pretrain_prediction = prediction['prediction']\n\n    test_rmse, test_mape = metric.rmse(prediction=td_de_normalizer(pretrain_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y)), \\\n                           metric.mape(prediction=td_de_normalizer(pretrain_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Target Domain Result')\n    print(test_rmse, test_mape)\n    writing_obj.append('%.5f' % test_rmse)\n\nif args['finetune'] == 'True':\n    try:\n        td_model.load(finetune_model_name)\n    except FileNotFoundError:\n        td_model.load(pretrain_model_name)\n        td_model.fit(closeness_feature=data_loader.td_loader.train_closeness,\n                     period_feature=data_loader.td_loader.train_period,\n                     trend_feature=data_loader.td_loader.train_trend,\n                     laplace_matrix=data_loader.td_loader.LM,\n                     target=data_loader.td_loader.train_y,\n                     external_feature=data_loader.td_loader.train_ef,\n                     sequence_length=data_loader.td_loader.train_sequence_len,\n                     output_names=('loss',),\n                     evaluate_loss_name='loss',\n                     op_names=('train_op',),\n                     batch_size=td_params['batch_size'],\n                     max_epoch=td_params['max_epoch'],\n                     validate_ratio=0.8,\n                     early_stop_method='t-test',\n                     early_stop_length=td_params['early_stop_length'],\n                     early_stop_patience=td_params['early_stop_patience'],\n                     verbose=True,\n                     save_model=True,\n                     save_model_name=finetune_model_name,\n                     auto_load_model=False)\n\n    td_model.load(finetune_model_name)\n\n    prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                  period_feature=data_loader.td_loader.test_period,\n                                  trend_feature=data_loader.td_loader.test_trend,\n                                  laplace_matrix=data_loader.td_loader.LM,\n                                  target=data_loader.td_loader.test_y,\n                                  external_feature=data_loader.td_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.td_loader.test_sequence_len,\n                                  cache_volume=td_params['batch_size'], )\n\n    finetune_prediction = prediction['prediction']\n\n    finetune_error_station = np.array([metric.rmse(td_de_normalizer(finetune_prediction[:, i]),\n                                                   td_de_normalizer(data_loader.td_loader.test_y[:, i]))\n                                                   for i in range(len(finetune_prediction[0]))])\n\n    test_rmse, test_mape = metric.rmse(prediction=td_de_normalizer(finetune_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y)), \\\n                           metric.mape(prediction=td_de_normalizer(finetune_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Target Domain Fine-tune')\n    print(test_rmse, test_mape)\n    writing_obj.append('%.5f' % test_rmse)\n\nif args['transfer'] == 'True':\n\n    try:\n        td_model.load(transfer_model_name)\n    except FileNotFoundError:\n\n        # save model for feature map\n        sd_model.load(pretrain_model_name)\n        sd_model.save(transfer_model_name, global_step=0)\n\n        traffic_sim = data_loader.checkin_sim()\n\n        sd_transfer_data = data_loader.sd_loader.train_data[-data_loader.td_loader.train_data.shape[0]:, :]\n\n        transfer_closeness, \\\n        transfer_period, \\\n        transfer_trend, \\\n        _ = data_loader.sd_loader.st_move_sample.move_sample(sd_transfer_data)\n\n        def callback_updating_fm():\n            global feature_maps\n            sd_model.load(transfer_model_name)\n            fm = sd_model.predict(closeness_feature=transfer_closeness,\n                                  period_feature=transfer_period,\n                                  trend_feature=transfer_trend,\n                                  laplace_matrix=data_loader.sd_loader.LM,\n                                  external_feature=data_loader.sd_loader.train_ef,\n                                  output_names=['feature_map'],\n                                  sequence_length=len(transfer_closeness),\n                                  cache_volume=sd_params['batch_size'])\n            return np.take(fm['feature_map'], np.array([e[1] for e in traffic_sim]), axis=1)\n\n\n        early_stop = EarlyStoppingTTest(length=20, p_value_threshold=0.1)\n\n        for epoch in range(td_params['max_epoch']):\n            # transfer\n            output_dict = td_model.fit(closeness_feature=data_loader.td_loader.train_closeness,\n                                       period_feature=data_loader.td_loader.train_period,\n                                       trend_feature=data_loader.td_loader.train_trend,\n                                       laplace_matrix=data_loader.td_loader.LM,\n                                       target=data_loader.td_loader.train_y,\n                                       external_feature=data_loader.td_loader.train_ef,\n                                       similar_feature_map=callback_updating_fm(),\n                                       sequence_length=data_loader.td_loader.train_sequence_len,\n                                       output_names=('transfer_loss', 'loss'),\n                                       evaluate_loss_name='loss',\n                                       op_names=('transfer_op',),\n                                       batch_size=td_params['batch_size'],\n                                       max_epoch=1,\n                                       validate_ratio=0.8,\n                                       early_stop_method='t-test',\n                                       early_stop_length=td_params['early_stop_length'],\n                                       early_stop_patience=td_params['early_stop_patience'],\n                                       verbose=True,\n                                       save_model=True,\n                                       save_model_name=transfer_model_name,\n                                       auto_load_model=False,\n                                       return_outputs=True)\n            if early_stop.stop(output_dict[-1]['val_loss']):\n                break\n\n    td_model.load(transfer_model_name)\n\n    prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                  period_feature=data_loader.td_loader.test_period,\n                                  trend_feature=data_loader.td_loader.test_trend,\n                                  laplace_matrix=data_loader.td_loader.LM,\n                                  target=data_loader.td_loader.test_y,\n                                  external_feature=data_loader.td_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.td_loader.test_sequence_len,\n                                  cache_volume=td_params['batch_size'], )\n\n    transfer_prediction = prediction['prediction']\n\n    transfer_error_station = np.array([metric.rmse(td_de_normalizer(transfer_prediction[:, i]),\n                                                   td_de_normalizer(data_loader.td_loader.test_y[:, i]))\n                                       for i in range(len(transfer_prediction[0]))])\n\n    test_rmse, test_mape = metric.rmse(prediction=td_de_normalizer(transfer_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y)), \\\n                           metric.mape(prediction=td_de_normalizer(transfer_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Target Domain Transfer')\n    print(test_rmse, test_mape)\n    writing_obj.append('%.5f' % test_rmse)\n\nwith open('transfer_record.md', 'a+', encoding='utf-8') as f:\n    f.write('|' + '|'.join(writing_obj) + '|' + '\\n')\n\n# Plot\n# data_loader.td_loader.st_map(build_order=finetune_error_station-transfer_error_station)\n\n# for index in range(0, data_loader.td_loader.station_number, 10):\n#\n#     show_prediction(pretrain=pretrain_prediction,\n#                     finetune=finetune_prediction,\n#                     transfer=transfer_prediction,\n#                     target=data_loader.td_loader.test_y,\n#                     station_index=index, start=0, end=500)"
  },
  {
    "path": "Experiments/STMeta_Transfer/STMeta_Transfer_Test.py",
    "content": "import os\nimport yaml\nimport argparse\nimport GPUtil\nimport numpy as np\n\nfrom UCTB.dataset import TransferDataLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\nfrom UCTB.train import EarlyStoppingTTest\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n\n#####################################################################\n# argument parser\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\nparser.add_argument('-m', '--model', default='STMeta_v4.model.yml')\nparser.add_argument('-sd', '--source_data', default='bike_nyc.data.yml')\nparser.add_argument('-td', '--target_data', default='bike_chicago.data.yml')\nparser.add_argument('-smd', '--similarity_mode', default='checkin')  # 'checkin', 'traffic', 'fake_traffic', 'poi'\nparser.add_argument('-tdl', '--target_data_length', default='1', type=str)\nparser.add_argument('-tfr', '--transfer_ratio', default='0.1', type=str)\nparser.add_argument('-pt', '--pretrain', default='True')\nparser.add_argument('-ft', '--finetune', default='True')\nparser.add_argument('-tr', '--transfer', default='True')\n\ndynamic_mode = False\n\nsd_regularization = True\n\nvalidate_mode = 'val'  # test\n\nval_ratio = 0.3\n\nargs = vars(parser.parse_args())\n\nsimilarity_mode = args['similarity_mode']  # 'checkin', 'traffic', 'fake_traffic', 'poi'\n\nwith open(args['model'].strip('./\\\\'), 'r') as f:\n    model_params = yaml.load(f)\n\nwith open(args['source_data'].strip('./\\\\'), 'r') as f:\n    sd_params = yaml.load(f)\n\nwith open(args['target_data'].strip('./\\\\'), 'r') as f:\n    td_params = yaml.load(f)\n\nassert sd_params['closeness_len'] == td_params['closeness_len']\nassert sd_params['period_len'] == td_params['period_len']\nassert sd_params['trend_len'] == td_params['trend_len']\n\n\ndef show_prediction(pretrain, finetune, transfer, target, station_index, start=0, end=-1):\n\n    import matplotlib.pyplot as plt\n\n    fig, axs = plt.subplots()\n\n    axs.plot(pretrain[start:end, station_index], 'b', label='pretrain')\n    axs.plot(finetune[start:end, station_index], 'g', label='finetune')\n    axs.plot(transfer[start:end, station_index], 'y', label='transfer')\n    axs.plot(target[start:end, station_index], 'r', label='target')\n\n    axs.grid()\n    axs.legend(fontsize=15)\n\n    axs.set_xlabel('Time', fontsize=15)\n    axs.set_ylabel('Demand', fontsize=15)\n\n    axs.set_title('Station/Grid %s' % station_index)\n\n    fig.set_size_inches(10, 5)\n    fig.savefig(os.path.join(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'PNG'),\n                             '%s.png' % 'station-%s' % station_index), dpi=150)\n    plt.close()\n\n#####################################################################\n# Generate code_version\ngroup = 'STMeta_Transfer'\ncode_version = 'STMeta_SD_{}_TD_{}'.format(args['source_data'].split('.')[0].split('_')[-1],\n                                                 args['target_data'].split('.')[0].split('_')[-1])\n\nsub_code_version = 'SR_C{}P{}T{}_G{}'.format(sd_params['closeness_len'], sd_params['period_len'], sd_params['trend_len'],\n                                             ''.join([e[0].upper() for e in sd_params['graph'].split('-')]))\n\nmodel_dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'model_dir')\nmodel_dir_path = os.path.join(model_dir_path, group)\n#####################################################################\n# Config data loader\n\ndata_loader = TransferDataLoader(sd_params, td_params, model_params, td_data_length=args['target_data_length'])\n\n# Import the Class:GraphGenerator\n# Call GraphGenerator to initialize and generate LM\ngraph = sd_params['graph']\nsd_graphBuilder = GraphGenerator(graph,\n                             dataset = data_loader.sd_loader.dataset,\n                             train_data = data_loader.sd_loader.train_data,\n                             traffic_data_index = data_loader.sd_loader.traffic_data_index,\n                             train_test_ratio = data_loader.sd_loader.train_test_ratio,\n                             threshold_distance=sd_params['threshold_distance'],\n                             threshold_correlation=sd_params['threshold_correlation'],\n                             threshold_interaction=sd_params['threshold_interaction'],\n                             )\n\ngraph = td_params['graph']\ntd_graphBuilder = GraphGenerator(graph,\n                             dataset = data_loader.td_loader.dataset,\n                             train_data = data_loader.td_loader.train_data,\n                             traffic_data_index = data_loader.td_loader.traffic_data_index,\n                             train_test_ratio = data_loader.td_loader.train_test_ratio,\n                             threshold_distance=td_params['threshold_distance'],\n                             threshold_correlation=td_params['threshold_correlation'],\n                             threshold_interaction=td_params['threshold_interaction'],\n                             )\n\ndeviceIDs = GPUtil.getAvailable(order='memory', limit=2, maxLoad=1, maxMemory=1,\n                                includeNan=False, excludeID=[], excludeUUID=[])\n\nif len(deviceIDs) == 0:\n    current_device = '-1'\nelse:\n    current_device = str(deviceIDs[0])\n\nsd_model = STMeta(num_node=data_loader.sd_loader.station_number,\n                  num_graph=sd_graphBuilder.LM.shape[0],\n                  external_dim=data_loader.sd_loader.external_dim,\n                  tpe_dim=data_loader.sd_loader.tpe_dim,\n                  code_version=code_version,\n                  model_dir=model_dir_path,\n                  gpu_device=current_device,\n                  build_sd_regularization=sd_regularization,\n                  transfer_ratio=0,\n                  **sd_params, **model_params)\nsd_model.build(init_vars=True)\n\ntransfer_ratio = float(args['transfer_ratio'])\n\ntd_model = STMeta(num_node=data_loader.td_loader.station_number,\n                  num_graph=td_graphBuilder.LM.shape[0],\n                  external_dim=data_loader.td_loader.external_dim,\n                  tpe_dim=data_loader.td_loader.tpe_dim,\n                  code_version=code_version,\n                  model_dir=model_dir_path,\n                  transfer_ratio=transfer_ratio,\n                  build_sd_regularization=False,\n                  gpu_device=current_device,\n                  **td_params, **model_params)\n\ntd_model.build(init_vars=False, max_to_keep=None)\n\nsd_de_normalizer = (lambda x: x) if sd_params['normalize'] is False \\\n                                else data_loader.sd_loader.normalizer.min_max_denormal\ntd_de_normalizer = (lambda x: x) if td_params['normalize'] is False \\\n                                else data_loader.td_loader.normalizer.min_max_denormal\n\nprint('#################################################################')\nprint('Source Domain information')\nprint(sd_params['dataset'], sd_params['city'])\nprint('Number of trainable variables', sd_model.trainable_vars)\nprint('Number of training samples', data_loader.sd_loader.train_sequence_len)\n\nprint('#################################################################')\nprint('Target Domain information')\nprint(td_params['dataset'], td_params['city'])\nprint('Number of trainable variables', td_model.trainable_vars)\nprint('Number of training samples', data_loader.td_loader.train_sequence_len)\n\npretrain_model_name = 'Pretrain_' + sub_code_version\nfinetune_model_name = 'Finetune_' + sub_code_version + '_' + str(data_loader.td_loader.train_sequence_len)\ntransfer_model_name = 'Transfer_' + sub_code_version + '_' + str(data_loader.td_loader.train_sequence_len) +\\\n                      '_%s' % int((transfer_ratio * 100)) + '%' + '_' + str(similarity_mode)\n\nwriting_obj = [''.join([e for e in sd_params['graph'].split('-')]),\n               similarity_mode,\n               args['source_data'].split('.')[0].split('_')[-1],\n               args['target_data'].split('.')[0].split('_')[-1],\n               str(transfer_ratio), '%s天' % args['target_data_length']]\n\nif args['pretrain'] == 'True':\n    try:\n        sd_model.load(pretrain_model_name)\n    except FileNotFoundError:\n        sd_model.fit(closeness_feature=data_loader.sd_loader.train_closeness,\n                     period_feature=data_loader.sd_loader.train_period,\n                     trend_feature=data_loader.sd_loader.train_trend,\n                     laplace_matrix=sd_graphBuilder.LM,\n                     target=data_loader.sd_loader.train_y,\n                    #  sd_sim=data_loader.checkin_sim_sd(),\n                     external_feature=data_loader.sd_loader.train_ef,\n                     sequence_length=data_loader.sd_loader.train_sequence_len,\n                     output_names=('loss',),\n                     evaluate_loss_name='loss',\n                     op_names=('train_op',),\n                     batch_size=sd_params['batch_size'],\n                     max_epoch=sd_params['max_epoch'],\n                     validate_ratio=0.1,\n                     early_stop_method='t-test',\n                     early_stop_length=sd_params['early_stop_length'],\n                     early_stop_patience=sd_params['early_stop_patience'],\n                     verbose=True,\n                     save_model=True)\n        sd_model.save(pretrain_model_name, global_step=0)\n\n    sd_model.load(pretrain_model_name)\n\n    prediction = sd_model.predict(closeness_feature=data_loader.sd_loader.test_closeness,\n                                  period_feature=data_loader.sd_loader.test_period,\n                                  trend_feature=data_loader.sd_loader.test_trend,\n                                  laplace_matrix=sd_graphBuilder.LM,\n                                  target=data_loader.sd_loader.test_y,\n                                  external_feature=data_loader.sd_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.sd_loader.test_sequence_len,\n                                  cache_volume=sd_params['batch_size'], )\n\n    test_prediction = prediction['prediction']\n\n    test_rmse, test_mape = metric.rmse(prediction=sd_de_normalizer(test_prediction),\n                                       target=sd_de_normalizer(data_loader.sd_loader.test_y)), \\\n                           metric.mape(prediction=sd_de_normalizer(test_prediction),\n                                       target=sd_de_normalizer(data_loader.sd_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Source Domain Result')\n    print(test_rmse, test_mape)\n\n    td_model.load(pretrain_model_name)\n\n    prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                  period_feature=data_loader.td_loader.test_period,\n                                  trend_feature=data_loader.td_loader.test_trend,\n                                  laplace_matrix=td_graphBuilder.LM,\n                                  target=data_loader.td_loader.test_y,\n                                  external_feature=data_loader.td_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.td_loader.test_sequence_len,\n                                  cache_volume=td_params['batch_size'], )\n\n    pretrain_prediction = prediction['prediction']\n\n    test_rmse, test_mape = metric.rmse(prediction=td_de_normalizer(pretrain_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y)), \\\n                           metric.mape(prediction=td_de_normalizer(pretrain_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Target Domain Result')\n    print(test_rmse, test_mape)\n    writing_obj.append('%.5f' % test_rmse)\n\nif args['finetune'] == 'True':\n    try:\n        td_model.load(finetune_model_name)\n    except FileNotFoundError:\n        td_model.load(pretrain_model_name)\n\n        early_stop = EarlyStoppingTTest(td_params['early_stop_length'], td_params['early_stop_patience'])\n        best_value = None\n        for epoch in range(td_params['max_epoch']):\n\n            output = td_model.fit(closeness_feature=data_loader.td_loader.train_closeness,\n                                  period_feature=data_loader.td_loader.train_period,\n                                  trend_feature=data_loader.td_loader.train_trend,\n                                  laplace_matrix=td_graphBuilder.LM,\n                                #   sd_sim=np.array(range(data_loader.td_loader.station_number), dtype=np.int32),\n                                  target=data_loader.td_loader.train_y,\n                                  external_feature=data_loader.td_loader.train_ef,\n                                  sequence_length=data_loader.td_loader.train_sequence_len,\n                                  output_names=('loss',),\n                                  evaluate_loss_name='loss',\n                                  op_names=('train_op',),\n                                  batch_size=td_params['batch_size'],\n                                  max_epoch=1,\n                                  validate_ratio=val_ratio,\n                                  early_stop_method='t-test',\n                                  early_stop_length=td_params['early_stop_length'],\n                                  early_stop_patience=td_params['early_stop_patience'],\n                                  verbose=True,\n                                  save_model=False,\n                                  save_model_name=None,\n                                  auto_load_model=False,\n                                  return_outputs=True)\n\n            prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                          period_feature=data_loader.td_loader.test_period,\n                                          trend_feature=data_loader.td_loader.test_trend,\n                                          laplace_matrix=td_graphBuilder.LM,\n                                          target=data_loader.td_loader.test_y,\n                                          external_feature=data_loader.td_loader.test_ef,\n                                          output_names=('prediction',),\n                                          sequence_length=data_loader.td_loader.test_sequence_len,\n                                          cache_volume=td_params['batch_size'], )\n\n            test_rmse = metric.rmse(prediction=td_de_normalizer(prediction['prediction']),\n                                    target=td_de_normalizer(data_loader.td_loader.test_y))\n\n            validate_error = output[-1]['val_loss'] if validate_mode == 'val' else test_rmse\n\n            if early_stop.stop(validate_error):\n                break\n\n            if best_value is None or best_value > validate_error:\n                best_value = validate_error\n                td_model.save(finetune_model_name, global_step=0)\n\n            print(epoch, 'test rmse', test_rmse)\n\n    td_model.load(finetune_model_name)\n    prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                  period_feature=data_loader.td_loader.test_period,\n                                  trend_feature=data_loader.td_loader.test_trend,\n                                  laplace_matrix=td_graphBuilder.LM,\n                                  target=data_loader.td_loader.test_y,\n                                  external_feature=data_loader.td_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.td_loader.test_sequence_len,\n                                  cache_volume=td_params['batch_size'], )\n    finetune_prediction = prediction['prediction']\n    finetune_error_station = np.array([metric.rmse(td_de_normalizer(finetune_prediction[:, i]),\n                                                   td_de_normalizer(data_loader.td_loader.test_y[:, i]))\n                                                   for i in range(len(finetune_prediction[0]))])\n    test_rmse, test_mape = metric.rmse(prediction=td_de_normalizer(finetune_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y)), \\\n                           metric.mape(prediction=td_de_normalizer(finetune_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Target Domain Fine-tune')\n    print(test_rmse, test_mape)\n    writing_obj.append('%.5f' % test_rmse)\n\nif args['transfer'] == 'True':\n\n    try:\n        td_model.load(transfer_model_name)\n    except FileNotFoundError:\n\n        sd_model.load(pretrain_model_name)\n        sd_model.save(transfer_model_name, global_step=0)\n        sd_transfer_data = data_loader.sd_loader.train_data[-data_loader.td_loader.train_data.shape[0]:, :]\n        transfer_closeness, \\\n        transfer_period, \\\n        transfer_trend, \\\n        _ = data_loader.sd_loader.st_move_sample.move_sample(sd_transfer_data)\n\n        if similarity_mode == 'checkin':\n            traffic_sim = data_loader.checkin_sim()\n        elif similarity_mode == 'poi':\n            traffic_sim = data_loader.poi_sim()\n        elif similarity_mode == 'traffic':\n            traffic_sim = data_loader.traffic_sim()\n        elif similarity_mode == 'fake_traffic':\n            traffic_sim = data_loader.traffic_sim_fake()\n\n        def dynamic_fm():\n            sd_model.load(transfer_model_name)\n            fm = sd_model.predict(closeness_feature=transfer_closeness,\n                                  period_feature=transfer_period,\n                                  trend_feature=transfer_trend,\n                                  laplace_matrix=sd_graphBuilder.LM,\n                                  external_feature=data_loader.sd_loader.train_ef,\n                                  output_names=['feature_map'],\n                                  sequence_length=len(transfer_closeness),\n                                  cache_volume=sd_params['batch_size'])\n            return np.take(fm['feature_map'], np.array([e[1] for e in traffic_sim]), axis=1)\n\n        feature_maps = dynamic_fm()\n\n        early_stop = EarlyStoppingTTest(td_params['early_stop_length'], td_params['early_stop_patience'])\n        td_model.load(pretrain_model_name)\n        best_value = None\n        for epoch in range(td_params['max_epoch']):\n\n            output = td_model.fit(closeness_feature=data_loader.td_loader.train_closeness,\n                                  period_feature=data_loader.td_loader.train_period,\n                                  trend_feature=data_loader.td_loader.train_trend,\n                                #   sd_sim=np.array(range(data_loader.td_loader.station_number), dtype=np.int32),\n                                  laplace_matrix=td_graphBuilder.LM,\n                                  target=data_loader.td_loader.train_y,\n                                  external_feature=data_loader.td_loader.train_ef,\n                                  similar_feature_map=feature_maps,\n                                  sequence_length=data_loader.td_loader.train_sequence_len,\n                                  output_names=('transfer_loss', 'loss'),\n                                  evaluate_loss_name='loss',\n                                  op_names=('transfer_op',),\n                                  batch_size=td_params['batch_size'],\n                                  max_epoch=1,\n                                  validate_ratio=val_ratio,\n                                  early_stop_method='t-test',\n                                  early_stop_length=td_params['early_stop_length'],\n                                  early_stop_patience=td_params['early_stop_patience'],\n                                  verbose=True,\n                                  save_model=False,\n                                  save_model_name=None,\n                                  auto_load_model=False,\n                                  return_outputs=True)\n\n            if dynamic_mode:\n                feature_maps = dynamic_fm()\n\n            prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                          period_feature=data_loader.td_loader.test_period,\n                                          trend_feature=data_loader.td_loader.test_trend,\n                                          laplace_matrix=td_graphBuilder.LM,\n                                          target=data_loader.td_loader.test_y,\n                                          external_feature=data_loader.td_loader.test_ef,\n                                          output_names=('prediction',),\n                                          sequence_length=data_loader.td_loader.test_sequence_len,\n                                          cache_volume=td_params['batch_size'], )\n\n            transfer_prediction = prediction['prediction']\n            test_rmse = metric.rmse(prediction=td_de_normalizer(prediction['prediction']),\n                                    target=td_de_normalizer(data_loader.td_loader.test_y))\n\n            validate_error = output[-1]['val_loss'] if validate_mode == 'val' else test_rmse\n\n            if early_stop.stop(validate_error):\n                break\n\n            if best_value is None or best_value > validate_error:\n                best_value = validate_error\n                td_model.save(transfer_model_name, global_step=0)\n\n            print(epoch, 'test rmse', test_rmse)\n\n    td_model.load(transfer_model_name)\n\n    prediction = td_model.predict(closeness_feature=data_loader.td_loader.test_closeness,\n                                  period_feature=data_loader.td_loader.test_period,\n                                  trend_feature=data_loader.td_loader.test_trend,\n                                  laplace_matrix=td_graphBuilder.LM,\n                                  target=data_loader.td_loader.test_y,\n                                  external_feature=data_loader.td_loader.test_ef,\n                                  output_names=('prediction',),\n                                  sequence_length=data_loader.td_loader.test_sequence_len,\n                                  cache_volume=td_params['batch_size'], )\n\n    transfer_prediction = prediction['prediction']\n\n    transfer_error_station = np.array([metric.rmse(td_de_normalizer(transfer_prediction[:, i]),\n                                                   td_de_normalizer(data_loader.td_loader.test_y[:, i]))\n                                       for i in range(len(transfer_prediction[0]))])\n\n    test_rmse, test_mape = metric.rmse(prediction=td_de_normalizer(transfer_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y)), \\\n                           metric.mape(prediction=td_de_normalizer(transfer_prediction),\n                                       target=td_de_normalizer(data_loader.td_loader.test_y), threshold=0)\n\n    print('#################################################################')\n    print('Target Domain Transfer')\n    print(test_rmse, test_mape)\n    writing_obj.append('%.5f' % test_rmse)\n\nwith open('transfer_record.md', 'a+', encoding='utf-8') as f:\n    f.write('|' + '|'.join(writing_obj) + '|' + '\\n')\n\n# Plot\n# data_loader.td_loader.st_map(build_order=finetune_error_station-transfer_error_station)\n\n# for index in range(0, data_loader.td_loader.station_number, 10):\n#\n#     show_prediction(pretrain=pretrain_prediction,\n#                     finetune=finetune_prediction,\n#                     transfer=transfer_prediction,\n#                     target=data_loader.td_loader.test_y,\n#                     station_index=index, start=0, end=500)"
  },
  {
    "path": "Experiments/STMeta_Transfer/STMeta_v1.model.yml",
    "content": "# network structure parameters\r\nst_method: 'gclstm'\r\ntemporal_merge: 'gal'\r\ngraph_merge: 'gal'\r\n\r\n# gcn parameters\r\ngcn_k: 1\r\ngcn_layers: 1\r\ngclstm_layers: 1\r\n\r\n# LSTM units\r\nnum_hidden_units: 64\r\n# dense units\r\nnum_filter_conv1x1: 32\r\n\r\n# merge parameters\r\ngraph_merge_gal_units: 64\r\ngraph_merge_gal_num_heads: 2\r\ntemporal_merge_gal_units: 64\r\ntemporal_merge_gal_num_heads: 2\r\n\r\nmodel_version: 'V1'"
  },
  {
    "path": "Experiments/STMeta_Transfer/STMeta_v2.model.yml",
    "content": "# network structure parameters\r\nst_method: 'gclstm'\r\ntemporal_merge: 'concat'\r\ngraph_merge: 'gal'\r\n\r\n# gcn parameters\r\ngcn_k: 1\r\ngcn_layers: 1\r\ngclstm_layers: 1\r\n\r\n# LSTM units\r\nnum_hidden_units: 64\r\n# dense units\r\nnum_filter_conv1x1: 32\r\n\r\n# merge parameters\r\ngraph_merge_gal_units: 64\r\ngraph_merge_gal_num_heads: 2\r\ntemporal_merge_gal_units: 64\r\ntemporal_merge_gal_num_heads: 2\r\n\r\nmodel_version: 'V2'"
  },
  {
    "path": "Experiments/STMeta_Transfer/STMeta_v3.model.yml",
    "content": "# network structure parameters\r\nst_method: 'gal_gcn'\r\ntemporal_merge: 'gal'\r\ngraph_merge: 'gal'\r\n\r\n# gcn parameters\r\ngcn_k: 1\r\ngcn_layers: 1\r\ngclstm_layers: 1\r\n\r\n# LSTM units\r\nnum_hidden_units: 64\r\n# dense units\r\nnum_filter_conv1x1: 32\r\n\r\n# temporal process params\r\ntemporal_gal_units: 32\r\ntemporal_gal_num_heads: 2\r\ntemporal_gal_layers: 4\r\n\r\n# merge parameters\r\ngraph_merge_gal_units: 64\r\ngraph_merge_gal_num_heads: 2\r\ntemporal_merge_gal_units: 64\r\ntemporal_merge_gal_num_heads: 2\r\n\r\nmodel_version: 'V3'"
  },
  {
    "path": "Experiments/STMeta_Transfer/STMeta_v4.model.yml",
    "content": "# network structure parameters\r\nst_method: 'gclstm'\r\ntemporal_merge: 'gal'\r\ngraph_merge: 'gal'\r\n\r\n# gcn parameters\r\ngcn_k: 1\r\ngcn_layers: 1\r\ngclstm_layers: 1\r\n\r\n# LSTM units\r\nnum_hidden_units: 64\r\n# dense units\r\nnum_filter_conv1x1: 32\r\n\r\n# merge parameters\r\ngraph_merge_gal_units: 64\r\ngraph_merge_gal_num_heads: 2\r\ntemporal_merge_gal_units: 64\r\ntemporal_merge_gal_num_heads: 2\r\n\r\nbuild_transfer: True\r\n\r\nmodel_version: 'V4'"
  },
  {
    "path": "Experiments/STMeta_Transfer/bike_chicago.data.yml",
    "content": "# dataset and city\r\ndataset: Bike\r\ncity: Chicago\r\n\r\ncloseness_len: 6\r\nperiod_len: 0\r\ntrend_len: 0\r\n\r\ngraph: Correlation\r\n\r\ndata_range: all\r\ntrain_data_length: '365'\r\n\r\nthreshold_distance: 1000\r\nthreshold_correlation: 0\r\nthreshold_interaction: 500\r\n\r\nnormalize: True\r\ntrain: True\r\n\r\ntest_ratio: 0.018\r\n\r\nlr: 0.00001\r\nearly_stop_length: 700\r\nearly_stop_patience: 0.1\r\nmax_epoch: 20000\r\nbatch_size: 64\r\n\r\ngroup: Chicago\r\nmark: 0"
  },
  {
    "path": "Experiments/STMeta_Transfer/bike_dc.data.yml",
    "content": "# dataset and city\r\ndataset: Bike\r\ncity: DC\r\n\r\ncloseness_len: 6\r\nperiod_len: 0\r\ntrend_len: 0\r\n\r\ngraph: Correlation\r\n\r\ndata_range: all\r\ntrain_data_length: '365'\r\n\r\nthreshold_distance: 1000\r\nthreshold_correlation: 0\r\nthreshold_interaction: 500\r\n\r\nnormalize: True\r\ntrain: True\r\n\r\ntest_ratio: 0.018\r\n\r\nlr: 0.00001\r\nearly_stop_length: 700\r\nearly_stop_patience: 0.1\r\nmax_epoch: 20000\r\nbatch_size: 64\r\n\r\ngroup: DC\r\nmark: 0"
  },
  {
    "path": "Experiments/STMeta_Transfer/bike_nyc.data.yml",
    "content": "# dataset and city\r\ndataset: Bike\r\ncity: NYC\r\n\r\ncloseness_len: 6\r\nperiod_len: 0\r\ntrend_len: 0\r\n\r\ngraph: Correlation\r\n\r\ndata_range: all\r\ntrain_data_length: '365'\r\n\r\nthreshold_distance: 1000\r\nthreshold_correlation: 0\r\nthreshold_interaction: 500\r\n\r\nnormalize: True\r\ntrain: True\r\n\r\ntest_ratio: 0.018\r\n\r\nlr: 0.00001\r\nearly_stop_length: 700\r\nearly_stop_patience: 0.1\r\nmax_epoch: 20000\r\nbatch_size: 64\r\n\r\ngroup: NYC\r\nmark: 0"
  },
  {
    "path": "Experiments/STMeta_Transfer/chargestation_beijing.data.yml",
    "content": "# dataset and city\r\ndataset: ChargeStation\r\ncity: Beijing\r\n\r\ncloseness_len: 6\r\nperiod_len: 7\r\ntrend_len: 4\r\n\r\ngraph: Correlation-Interaction-Distance\r\n\r\ndata_range: all\r\ntrain_data_length: all\r\n\r\nthreshold_distance: 1000\r\nthreshold_correlation: 0.1\r\nthreshold_interaction: 500\r\n\r\nnormalize: True\r\ntrain: True\r\n\r\nlr: 1e-5\r\nearly_stop_length: 500\r\nearly_stop_patience: 0.1\r\nmax_epoch: 20000\r\nbatch_size: 8\r\ngpu_device: 0,1\r\n\r\ngroup: Beijing\r\nmark: 0"
  },
  {
    "path": "Experiments/STMeta_Transfer/didi_chengdu.data.yml",
    "content": "# dataset and city\ndataset: DiDi\ncity: Chengdu\n\ncloseness_len: 6\nperiod_len: 0\ntrend_len: 0\n\ngraph: Distance\n\ndata_range: all\ntrain_data_length: all\n\nthreshold_distance: 7500\nthreshold_correlation: 0.65\nthreshold_interaction: 30\n\nnormalize: True\ntrain: True\n\nlr: 0.00001\nearly_stop_length: 50\nearly_stop_patience: 0.1\nmax_epoch: 20000\nbatch_size: 128\n\ngroup: Chengdu"
  },
  {
    "path": "Experiments/STMeta_Transfer/didi_xian.data.yml",
    "content": "# dataset and city\ndataset: DiDi\ncity: Xian\n\ncloseness_len: 6\nperiod_len: 0\ntrend_len: 0\n\ngraph: Distance\n\ndata_range: all\ntrain_data_length: all\n\nthreshold_distance: 7500\nthreshold_correlation: 0.65\nthreshold_interaction: 30\n\nnormalize: True\ntrain: True\n\nlr: 0.00002\nearly_stop_length: 50\nearly_stop_patience: 0.1\nmax_epoch: 20000\nbatch_size: 128\n\ngroup: Xian"
  },
  {
    "path": "Experiments/STMeta_Transfer/metro_chongqing.data.yml",
    "content": "# dataset and city\r\ndataset: Metro\r\ncity: Chongqing\r\n\r\ncloseness_len: 6\r\nperiod_len: 0\r\ntrend_len: 0\r\n\r\ngraph: Correlation\r\n\r\ndata_range: all\r\ntrain_data_length: all\r\n\r\nthreshold_distance: 5000\r\nthreshold_correlation: 0.7\r\nthreshold_interaction: 30\r\n\r\nnormalize: True\r\ntrain: True\r\n\r\nlr: 0.00001\r\nearly_stop_length: 500\r\nearly_stop_patience: 0.1\r\nmax_epoch: 20000\r\nbatch_size: 128\r\n\r\ngroup: Chongqing"
  },
  {
    "path": "Experiments/STMeta_Transfer/metro_shanghai.data.yml",
    "content": "# dataset and city\r\ndataset: Metro\r\ncity: ShanghaiV1\r\n\r\ncloseness_len: 6\r\nperiod_len: 0\r\ntrend_len: 0\r\n\r\ngraph: Correlation\r\n\r\ndata_range: all\r\ntrain_data_length: all\r\n\r\nthreshold_distance: 5000\r\nthreshold_correlation: 0.7\r\nthreshold_interaction: 30\r\n\r\nnormalize: True\r\ntrain: True\r\n\r\nlr: 0.00001\r\nearly_stop_length: 500\r\nearly_stop_patience: 0.1\r\nmax_epoch: 10000\r\nbatch_size: 128\r\n\r\ngroup: Shanghai"
  },
  {
    "path": "Experiments/STMeta_Transfer/network_search.json",
    "content": "{\r\n    \"st_method\": {\"_type\":\"choice\",\"_value\":[\"gclstm\", \"gal_gcn\"]},\r\n\r\n    \"temporal_merge\": {\"_type\":\"choice\",\"_value\":[\"concat\", \"gal\"]},\r\n\r\n    \"graph_merge\": {\"_type\":\"choice\",\"_value\":[\"concat\", \"gal\"]}\r\n}"
  },
  {
    "path": "Experiments/STMeta_Transfer/param_search.yml",
    "content": "authorName: DiChai\r\nexperimentName: network_search\r\ntrialConcurrency: 1\r\nmaxExecDuration: 24h\r\nmaxTrialNum: 50\r\ntrainingServicePlatform: local\r\n# The path to Search Space\r\nsearchSpacePath: search_space.json\r\nuseAnnotation: false\r\ntuner:\r\n  builtinTunerName: GridSearch\r\n# The path and the running command of trial\r\ntrial:\r\n  command: python STMeta_V3_Obj.py -y metro_shanghai.yml\r\n  codeDir: .\r\n  gpuNum: 1"
  },
  {
    "path": "Experiments/STMeta_Transfer/transfer_record.md",
    "content": "\n|    Graph    | Match        |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :---------: | ------------ | :-----: | :-----: | :------------: | :-------------: | :-------: | :-----: | :---------: |\n|Distance|checkin|nyc|chicago|0.1|1天|4.70441|4.70361|12.59841|\n|Distance|checkin|nyc|chicago|0.1|3天|4.70441|4.82347|4.78770|\n|Distance|checkin|nyc|chicago|0.1|5天|4.70441|4.83354|4.81036|\n|Distance|checkin|nyc|chicago|0.1|7天|4.70441|4.70070|4.74429|\n|Distance|checkin|nyc|dc|0.1|1天|4.18998|4.18815|4.18669|\n|Distance|checkin|nyc|dc|0.1|3天|4.18998|3.95583|3.95511|\n|Distance|checkin|nyc|dc|0.1|5天|4.18998|3.96894|4.01603|\n|Distance|checkin|chicago|dc|0.1|1天|3.19900|3.10418|3.11494|\n|Distance|checkin|chicago|dc|0.1|3天|3.19900|3.00662|3.13352|\n|Distance|checkin|chicago|dc|0.1|5天|3.19900|2.98474|2.99215|\n|Distance|checkin|chicago|dc|0.1|7天|3.19900|2.89581|2.94413|\n|Distance|checkin|chicago|nyc|0.1|1天|10.24455|9.44282|12.85142|\n|Distance|checkin|chicago|nyc|0.1|3天|10.24455|6.87987|12.93270|\n|Distance|checkin|chicago|nyc|0.1|5天|10.24455|10.21737|13.56898|\n|Distance|checkin|chicago|nyc|0.1|7天|10.24455|6.66069|12.12317|\n|Distance|checkin|dc|nyc|0.1|1天|7.23524|7.23436|7.23350|\n|Distance|checkin|dc|nyc|0.1|3天|7.23524|6.73650|6.81929|\n|Distance|checkin|dc|nyc|0.1|5天|7.23524|7.23440|7.23744|\n|Distance|checkin|dc|nyc|0.1|7天|7.23524|7.23836|7.23745|\n|Distance|checkin|dc|chicago|0.1|1天|4.34642|4.35396|4.34736|\n|Distance|checkin|dc|chicago|0.1|5天|4.34642|4.49737|4.39714|\n|Distance|checkin|dc|chicago|0.1|7天|4.34642|4.49232|4.37209|\n|Distance|checkin|dc|chicago|0.1|3天|4.34642|4.46849|4.47618|\n|Distance|checkin|nyc|chicago|0.1|1天|4.70441|4.70361|12.59841|\n|Distance|checkin|dc|chicago|0.1|1天|4.34642|4.35396|4.34736|\n|Distance|checkin|chicago|dc|0.1|1天|3.19900|3.10418|3.11494|\n\n#### Tuning the transfer-ratio\n\n|    Graph    | Match        |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :---------: | ------------ | :-----: | :-----: | :------------: | :-------------: | :-------: | :-----: | :---------: |\n|Correlation|checkin|nyc|chicago|0.2|1天|4.67712|3.92269|3.99346|\n|Correlation|checkin|nyc|chicago|0.2|3天|4.22121|3.70951|3.71976|\n|Correlation|checkin|nyc|chicago|0.2|5天|4.32650|4.02932|4.06536|\n|Correlation|checkin|nyc|chicago|0.2|7天|3.77726|3.61502|3.64801|\n|Correlation|checkin|nyc|chicago|0.3|1天|4.67712|3.92269|3.99815|\n|Correlation|checkin|nyc|chicago|0.3|3天|4.22121|3.70951|3.72503|\n|Correlation|checkin|nyc|chicago|0.3|5天|4.32650|4.02932|4.03297|\n|Correlation|checkin|nyc|chicago|0.3|7天|3.77726|3.61502|3.64506|\n|Correlation|checkin|nyc|dc|0.2|1天|3.77775|3.41215|3.40791|\n|Correlation|checkin|nyc|dc|0.2|3天|3.53591|3.25796|3.23612|\n|Correlation|checkin|nyc|dc|0.2|5天|3.39463|3.39892|3.38755|\n|Correlation|checkin|nyc|dc|0.2|7天|3.38310|3.29268|3.28780|\n|Correlation|checkin|nyc|dc|0.3|1天|3.77775|3.41215|3.41827|\n|Correlation|checkin|nyc|dc|0.3|3天|3.53591|3.25796|3.23804|\n|Correlation|checkin|nyc|dc|0.3|5天|3.39463|3.39892|3.39739|\n|Correlation|checkin|nyc|dc|0.3|7天|3.38310|3.29268|3.29109|\n|Correlation|checkin|chicago|dc|0.2|1天|3.78157|3.71789|3.69212|\n|Correlation|checkin|chicago|dc|0.2|3天|3.69740|3.14304|3.24586|\n|Correlation|checkin|chicago|dc|0.2|5天|3.62814|3.17226|3.19682|\n|Correlation|checkin|chicago|dc|0.2|7天|3.58433|3.11757|3.16523|\n|Correlation|checkin|chicago|dc|0.3|1天|3.78157|3.71789|3.69082|\n|Correlation|checkin|chicago|dc|0.3|3天|3.69740|3.14304|3.18183|\n|Correlation|checkin|chicago|dc|0.3|5天|3.62814|3.17226|3.20910|\n|Correlation|checkin|chicago|dc|0.3|7天|3.58433|3.11757|3.18558|\n|Correlation|checkin|chicago|nyc|0.2|1天|7.54476|6.90001|7.05806|\n|Correlation|checkin|chicago|nyc|0.2|3天|7.22262|6.81500|6.82105|\n|Correlation|checkin|chicago|nyc|0.2|5天|7.13852|6.79075|7.10494|\n|Correlation|checkin|chicago|nyc|0.2|7天|7.12167|6.56041|7.08145|\n|Correlation|checkin|chicago|nyc|0.3|1天|7.33929|7.14455|7.04937|\n|Correlation|checkin|chicago|nyc|0.3|3天|7.22262|6.86183|7.53325|\n|Correlation|checkin|chicago|nyc|0.3|5天|7.13852|6.71483|7.11741|\n|Correlation|checkin|chicago|nyc|0.3|7天|7.12167|6.56041|7.10332|\n|Correlation|checkin|dc|nyc|0.2|1天|9.42764|7.78120|7.59939|\n|Correlation|checkin|dc|nyc|0.2|3天|7.92233|6.85930|7.58509|\n|Correlation|checkin|dc|nyc|0.2|5天|20.37170|7.60804|7.87388|\n|Correlation|checkin|dc|nyc|0.2|7天|7.81039|6.86581|7.75423|\n|Correlation|checkin|dc|nyc|0.3|1天|9.42764|7.78120|7.65509|\n|Correlation|checkin|dc|nyc|0.3|3天|7.92233|6.85930|7.49069|\n|Correlation|checkin|dc|nyc|0.3|5天|7.87232|7.60804|16.16995|\n|Correlation|checkin|dc|nyc|0.3|7天|7.81039|6.86581|7.81060|\n|Correlation|checkin|dc|chicago|0.2|1天|10.58203|4.67799|4.73050|\n|Correlation|checkin|dc|chicago|0.2|3天|11.23320|3.90123|3.57875|\n|Correlation|checkin|dc|chicago|0.2|5天|9.93056|3.79625|3.40253|\n|Correlation|checkin|dc|chicago|0.2|7天|8.54751|4.06583|3.40602|\n|Correlation|checkin|dc|chicago|0.3|1天|10.58203|4.67799|4.88579|\n|Correlation|checkin|dc|chicago|0.3|3天|11.23320|3.90123|3.59715|\n|Correlation|checkin|dc|chicago|0.3|5天|9.93056|3.79625|3.43136|\n|Correlation|checkin|dc|chicago|0.3|7天|8.54751|4.06583|3.42706|\n|Correlation|checkin|nyc|chicago|0.05|1天|4.67712|3.92269|3.97959|\n|Correlation|checkin|nyc|chicago|0.05|3天|4.22121|3.70951|3.73577|\n|Correlation|checkin|nyc|chicago|0.05|5天|4.32650|4.02932|4.10112|\n|Correlation|checkin|nyc|chicago|0.05|7天|3.77726|3.61502|3.63231|\n|Correlation|checkin|nyc|dc|0.05|1天|3.77775|3.41215|3.24400|\n|Correlation|checkin|nyc|dc|0.05|3天|3.53591|3.25796|3.24783|\n|Correlation|checkin|nyc|dc|0.05|5天|3.39463|3.39892|3.38714|\n|Correlation|checkin|nyc|dc|0.05|7天|3.38310|3.29268|3.27108|\n|Correlation|checkin|chicago|dc|0.05|1天|3.78157|3.71789|3.69419|\n|Correlation|checkin|chicago|dc|0.05|3天|3.69740|3.14304|3.14949|\n|Correlation|checkin|chicago|dc|0.05|5天|3.62814|3.17226|3.17349|\n|Correlation|checkin|chicago|dc|0.05|7天|3.58433|3.11757|3.12788|\n|Correlation|checkin|chicago|nyc|0.05|1天|7.33929|6.90001|6.94973|\n|Correlation|checkin|chicago|nyc|0.05|3天|7.22262|7.01002|6.79002|\n|Correlation|checkin|chicago|nyc|0.05|5天|7.13852|6.71483|7.11115|\n|Correlation|checkin|chicago|nyc|0.05|7天|7.12167|6.56041|7.09967|\n|Correlation|checkin|dc|nyc|0.05|1天|9.42764|7.78120|7.38421|\n|Correlation|checkin|dc|nyc|0.05|3天|7.92233|6.85930|12.42980|\n|Correlation|checkin|dc|nyc|0.05|5天|7.87232|7.60804|7.80362|\n|Correlation|checkin|dc|nyc|0.05|7天|7.81039|6.86581|7.81139|\n|Correlation|checkin|dc|chicago|0.05|1天|10.58203|4.67799|4.54821|\n|Correlation|checkin|dc|chicago|0.05|3天|11.23320|3.90123|3.58257|\n|Correlation|checkin|dc|chicago|0.05|5天|9.93056|3.79625|3.43679|\n|Correlation|checkin|dc|chicago|0.05|7天|8.54751|4.06583|3.39452|\n\n#### Dynamic mode\n\n| TrainMode |   SD    |   TD    | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :-----: | :-----: | :------------: | :-------: | :-----: | :---------: | :---------: |\n|dynamic|nyc|chicago|1天|4.67712|3.92269|3.99061|\n|dynamic|nyc|chicago|3天|4.22121|3.72731|3.72169|\n|dynamic|nyc|chicago|5天|4.32650|4.03527|4.09383|\n|dynamic|nyc|chicago|7天|3.77726|3.62886|3.64174|\n|dynamic|nyc|dc|1天|3.77775|3.41219|3.24365|\n|dynamic|nyc|dc|3天|3.53591|3.24496|3.23717|\n|dynamic|nyc|dc|5天|3.39463|3.39877|3.41054|\n|dynamic|nyc|dc|7天|3.38310|3.29157|3.27758|\n|dynamic|chicago|dc|1天|3.78157|3.71789|3.69317|\n|dynamic|chicago|dc|3天|3.69740|3.14631|3.18608|\n|dynamic|chicago|dc|5天|3.62814|3.17078|3.19249|\n|dynamic|chicago|dc|7天|3.58433|3.11549|3.15131|\n|dynamic|chicago|nyc|1天|7.33929|7.38597|6.96449|\n|dynamic|chicago|nyc|3天|7.55972|6.80038|6.77189|\n|dynamic|chicago|nyc|5天|7.13852|6.68604|7.10314|\n|dynamic|chicago|nyc|7天|7.12167|6.67103|7.09394|\n|dynamic|dc|nyc|1天|9.41977|7.78120|25.48727|\n|dynamic|dc|nyc|3天|7.92233|6.93770|8.94962|\n|dynamic|dc|nyc|5天|7.87232|7.67169|7.87556|\n|dynamic|dc|nyc|7天|24.38127|7.73380|7.81032|\n|dynamic|dc|chicago|1天|10.58203|4.67799|4.75832|\n|dynamic|dc|chicago|3天|11.23320|3.82442|4.21488|\n|dynamic|dc|chicago|5天|9.93056|3.79295|3.91066|\n|dynamic|dc|chicago|7天|8.54751|4.08669|3.75169||Correlation|checkin|dc|nyc|0.1|1天|9.42764|7.78120|14.34273|\n|Correlation|checkin|dc|nyc|0.1|1天|9.42764|7.78120|7.75579|\n\n\n\n|    Graph    | Match        |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :---------: | ------------ | :-----: | :-----: | :------------: | :-------------: | :-------: | :-----: | :---------: |\n|Correlation|checkin|nyc|chicago|0.1|1天|4.76519|3.91774|4.00033|\n|Correlation|checkin|nyc|chicago|0.1|3天|4.21627|3.69943|3.71308|\n|Correlation|checkin|nyc|chicago|0.1|7天|3.77277|3.62399|3.64341|\n|Correlation|checkin|nyc|dc|0.1|1天|3.77953|3.40973|3.27021|\n|Correlation|checkin|nyc|dc|0.1|3天|3.53572|3.25625|3.24498|\n|Correlation|checkin|nyc|dc|0.1|5天|3.39470|3.39883|3.39262|\n|Correlation|checkin|nyc|dc|0.1|7天|3.38312|3.29258|3.27573|\n|Correlation|checkin|chicago|dc|0.1|1天|3.78083|3.71714|3.69250|\n|Correlation|checkin|chicago|dc|0.1|3天|3.69748|3.14352|3.15632|\n|Correlation|checkin|chicago|dc|0.1|5天|3.62816|3.17147|3.17755|\n|Correlation|checkin|chicago|dc|0.1|7天|3.58449|3.11533|3.14646|\n|Correlation|checkin|chicago|nyc|0.1|1天|7.33863|6.90045|6.96378|\n|Correlation|checkin|chicago|nyc|0.1|3天|7.22249|6.85352|6.79605|\n|Correlation|checkin|chicago|nyc|0.1|5天|7.13851|6.70580|7.09479|\n|Correlation|checkin|chicago|nyc|0.1|7天|7.12164|6.69556|7.10098|\n|Correlation|checkin|dc|nyc|0.1|1天|9.38367|7.77615|7.49206|\n|Correlation|checkin|dc|nyc|0.1|3天|7.92180|6.91332|7.66319|\n|Correlation|checkin|dc|nyc|0.1|5天|7.87216|7.61887|7.87342|\n|Correlation|checkin|dc|nyc|0.1|7天|7.81035|7.09896|7.81083|\n|Correlation|checkin|dc|chicago|0.1|1天|10.60726|4.71315|4.52085|\n|Correlation|checkin|nyc|chicago|0.1|1天|4.40424|6.09647|4.68890|\n|Correlation|checkin|nyc|chicago|0.1|1天|4.40412|6.10487|4.69186|\n"
  },
  {
    "path": "Experiments/STMeta_Transfer/transfer_record_bk.md",
    "content": "#### Correlation graph transfer result, match using traffic flow (30 days)\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|nyc|chicago|0.1|1天|4.67712|4.67061|**4.50287**|\n|nyc|chicago|0.1|3天|4.22121|**3.86823**|4.97310|\n|nyc|chicago|0.1|5天|4.32650|**3.83584**|3.89576|\n|nyc|chicago|0.1|7天|3.77726|**3.64761**|3.69924|\n|nyc|dc|0.1|1天|3.77775|3.60307|**3.31033**|\n|nyc|dc|0.1|3天|3.53591|**3.19822**|3.27654|\n|nyc|dc|0.1|5天|3.39463|3.31562|**3.31375**|\n|nyc|dc|0.1|7天|3.38310|3.22907|**3.22316**|\n|dc|nyc|0.1|1天|9.42764|**7.69555**|8.03807|\n|dc|nyc|0.1|3天|7.92233|**7.86374**|7.87504|\n|dc|nyc|0.1|5天|7.87232|**7.57717**|7.87731|\n|dc|nyc|0.1|7天|7.81039|**7.74953**|7.79245|\n|dc|chicago|0.1|1天|10.58203|5.11785|**4.89390**|\n|dc|chicago|0.1|3天|11.23320|12.65670|**4.74284**|\n|dc|chicago|0.1|5天|9.93056|4.28090|**3.47838**|\n|dc|chicago|0.1|7天|8.54751|**3.32681**|3.38316|\n|chicago|nyc|0.1|1天|7.33929|**6.98808**|7.01758|\n|chicago|nyc|0.1|3天|7.22262|**7.03898**|7.28277|\n|chicago|nyc|0.1|5天|7.13852|**6.80380**|7.12489|\n|chicago|nyc|0.1|7天|7.12167|**6.63963**|7.07976|\n|chicago|dc|0.1|1天|3.78157|3.75912|**3.75336**|\n|chicago|dc|0.1|3天|3.69740|**3.58552**|3.62116|\n|chicago|dc|0.1|5天|3.62814|**3.15233**|3.40723|\n\n#### Correlation graph transfer result，match with check-in feature\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|nyc|chicago|0.1|1天|4.67712|4.67061|**4.49448**|\n|nyc|chicago|0.1|3天|4.22121|4.52615|**3.87400**|\n|nyc|chicago|0.1|5天|4.32650|**3.89086**|3.94352|\n|nyc|chicago|0.1|7天|3.77726|**3.64852**|3.69911|\n|nyc|dc|0.1|1天|3.77775|3.60307|**3.27499**|\n|nyc|dc|0.1|3天|3.53591|3.42623|**3.38511**|\n|nyc|dc|0.1|5天|3.39463|**3.29540**|3.32153|\n|nyc|dc|0.1|7天|3.38310|3.24432|**3.23480**|\n|dc|nyc|0.1|1天|9.42764|**7.69555**|7.95242|\n|dc|nyc|0.1|3天|7.92233|**7.87700**|8.12669|\n|dc|nyc|0.1|5天|7.87232|**7.64216**|7.86986|\n|dc|nyc|0.1|7天|7.81039|**7.74056**|7.79816|\n|dc|chicago|0.1|1天|10.58203|5.11785|**4.88025**|\n|dc|chicago|0.1|3天|11.23320|5.46448|**4.44395**|\n|dc|chicago|0.1|5天|9.93056|4.30427|**3.44833**|\n|dc|chicago|0.1|7天|8.54751|**3.28179**|3.34347|\n|chicago|nyc|0.1|1天|7.33929|**6.98808**|7.02008|\n|chicago|nyc|0.1|3天|7.22262|7.36530|**7.00954**|\n|chicago|nyc|0.1|5天|7.13852|**6.63782**|7.13790|\n|chicago|nyc|0.1|7天|7.12167|**6.73726**|7.09331|\n|chicago|dc|0.1|1天|3.78157|3.75912|**3.75527**|\n|chicago|dc|0.1|3天|3.69740|**3.61495**|3.62228|\n|chicago|dc|0.1|5天|3.62814|**3.14687**|3.17531|\n|chicago|dc|0.1|7天|3.58433|**3.07332**|3.10778|\n\n#### Distance Graph，Check-In feature，Dynamic training\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|nyc|chicago|0.1|1天|**4.70441**|5.17771|5.13792|\n|nyc|chicago|0.1|3天|**4.70441**|5.24400|5.40755|\n|nyc|chicago|0.1|5天|4.70441|4.71439|**4.68781**|\n|nyc|chicago|0.1|7天|4.70441|4.71179|**4.57209**|\n|nyc|dc|0.1|1天|4.18998|4.18247|**3.94269**|\n|nyc|dc|0.1|3天|4.18998|**4.13482**|4.14903|\n|nyc|dc|0.1|5天|4.18998|3.86709|**3.86132**|\n|nyc|dc|0.1|7天|4.18998|3.63065|**3.61484**|\n|dc|nyc|0.1|1天|7.23524|**7.23120**|8.61836|\n|dc|nyc|0.1|3天|7.23524|**6.33199**|6.35476|\n|dc|nyc|0.1|5天|**7.23524**|7.24360|8.84953|\n|dc|nyc|0.1|7天|**7.23524**|7.26807|9.24907|\n|dc|chicago|0.1|1天|4.34642|4.37925|**4.35733**|\n|dc|chicago|0.1|3天|**4.34642**|4.39791|4.54773|\n|dc|chicago|0.1|5天|**4.34642**|4.51153|4.46805|\n|dc|chicago|0.1|7天|4.34642|4.04295|**4.00917**|\n|chicago|nyc|0.1|1天|**10.24455**|12.02121|15.36785|\n|chicago|nyc|0.1|3天|**10.24455**|12.11566|15.38250|\n|chicago|nyc|0.1|5天|**10.24455**|10.90358|13.41528|\n|chicago|nyc|0.1|7天|10.24455|6.71849|**6.71550**|\n|chicago|dc|0.1|1天|3.19900|**3.09946**|3.23995|\n|chicago|dc|0.1|3天|3.19900|3.14234|**3.12200**|\n|chicago|dc|0.1|5天|3.19900|**2.99568**|3.16543|\n|chicago|dc|0.1|7天|3.19900|**2.92313**|3.07769|\n\n#### Distance Graph，Check-In feature，Dynamic training\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|nyc|chicago|0.1|1天|**4.70441**|5.17771|5.13792|\n|nyc|chicago|0.1|3天|**4.70441**|5.02598|4.85231|\n|nyc|chicago|0.1|5天|4.70441|4.79848|**4.65276**|\n|nyc|chicago|0.1|7天|4.70441|4.72065|**4.58330**|\n|nyc|dc|0.1|1天|4.18998|4.18247|**3.94269**|\n|nyc|dc|0.1|3天|4.18998|4.02759|**3.91673**|\n|nyc|dc|0.1|5天|4.18998|3.87307|**3.85373**|\n|nyc|dc|0.1|7天|4.18998|3.66314|**3.61744**|\n|dc|nyc|0.1|1天|7.23524|**7.23120**|8.61836|\n|dc|nyc|0.1|3天|7.23524|7.18937|**6.76861**|\n|dc|nyc|0.1|5天|**7.23524**|7.24310|8.85444|\n|dc|nyc|0.1|7天|**7.23524**|7.26563|9.23842|\n|dc|chicago|0.1|1天|**4.34642**|4.37925|4.35733|\n|dc|chicago|0.1|3天|**4.34642**|4.39091|4.61458|\n|dc|chicago|0.1|5天|**4.34642**|4.51621|4.47188|\n|dc|chicago|0.1|7天|4.34642|4.07226|**4.03542**|\n|chicago|nyc|0.1|1天|**10.24455**|12.02121|15.36785|\n|chicago|nyc|0.1|3天|**10.24455**|10.99130|16.56082|\n|chicago|nyc|0.1|5天|10.24455|**6.69829**|6.78793|\n|chicago|nyc|0.1|7天|10.24455|**6.89889**|7.57003|\n|chicago|dc|0.1|1天|3.19900|**3.09946**|3.23995|\n|chicago|dc|0.1|3天|3.19900|**3.12949**|3.18817|\n|chicago|dc|0.1|5天|3.19900|**3.02039**|3.18615|\n|chicago|dc|0.1|7天|3.19900|**2.90374**|3.11075|\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|nyc|chicago|0.1|1天|4.70441|5.17771|5.13792|\n|nyc|chicago|0.1|3天|4.70441|4.80959|4.94123|\n|nyc|chicago|0.1|5天|4.70441|4.77160|4.68924|\n|nyc|chicago|0.1|7天|4.70441|4.77123|4.57228|\n|nyc|dc|0.1|1天|4.18998|4.18247|3.94269|\n|nyc|dc|0.1|3天|4.18998|4.05417|4.09441|\n|nyc|dc|0.1|5天|4.18998|3.92515|3.92526|\n|nyc|dc|0.1|7天|4.18998|3.67485|3.62186|\n|dc|nyc|0.1|1天|7.23524|7.23120|8.61836|\n|dc|nyc|0.1|3天|7.23524|6.36652|6.29304|\n|dc|nyc|0.1|5天|7.23524|8.12606|8.13084|\n|dc|nyc|0.1|7天|7.23524|7.26382|9.24113|\n|dc|chicago|0.1|1天|4.34642|4.37925|4.35733|\n|dc|chicago|0.1|3天|4.34642|4.40805|4.60000|\n|dc|chicago|0.1|5天|4.34642|4.49298|4.48141|\n|dc|chicago|0.1|7天|4.34642|4.03225|3.99625|\n|chicago|nyc|0.1|1天|10.24455|12.02121|15.36785|\n|chicago|nyc|0.1|3天|10.24455|12.84052|12.39428|\n|chicago|nyc|0.1|5天|10.24455|10.32351|13.51593|\n|chicago|nyc|0.1|7天|10.24455|11.71842|11.97301|\n|chicago|dc|0.1|1天|3.19900|3.09946|3.23995|\n|chicago|dc|0.1|3天|3.19900|3.09866|3.20144|\n|chicago|dc|0.1|5天|3.19900|3.03267|3.18821|\n|chicago|dc|0.1|7天|3.19900|2.90296|3.09439|\n\n#### Running tests\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|nyc|chicago|0.1|1天|4.67712|4.17206|4.35158|\n|nyc|chicago|0.1|3天|4.22121|4.40948|4.67440|\n|nyc|chicago|0.1|5天|4.32650|3.81700|3.92837|\n|nyc|chicago|0.1|7天|3.77726|3.63045|3.66386|\n|nyc|dc|0.1|1天|3.77775|3.23772|3.47581|\n|nyc|dc|0.1|3天|3.53591|3.30477|3.81137|\n|nyc|dc|0.1|5天|3.39463|3.32380|3.32734|\n|nyc|dc|0.1|7天|3.38310|3.24348|3.26136|\n\n| Graph |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: | :---------: |\n||nyc|chicago|0.3|1天|4.67712|4.17237|4.04008|\n||nyc|chicago|0.3|3天|4.22121|4.22041|4.08511|\n||nyc|chicago|0.3|5天|4.32650|3.94659|3.86648|\n||nyc|chicago|0.3|7天|3.77726|3.64293|3.65762|\n||nyc|dc|0.3|1天|3.77775|3.23772|3.44210|\n||nyc|dc|0.3|3天|3.53591|3.36918|3.32675|\n||nyc|dc|0.3|5天|3.39463|3.32176|3.32761|\n||nyc|dc|0.3|7天|3.38310|3.24480|3.34377|\n||nyc|dc|0.5|1天|3.77775|3.40004|3.78089|\n||nyc|dc|0.3|1天|3.77775|3.39991|3.52524|\n||nyc|dc|0.3|3天|3.53591|3.23931|3.46197|\n||nyc|dc|0.3|5天|3.39463|3.31526|3.35127|\n||nyc|dc|0.3|7天|3.38310|3.23292|3.26009|\n||nyc|dc|0.2|1天|3.77775|3.39991|3.48174|\n||nyc|dc|0.2|3天|3.53591|3.23931|3.36759|\n||nyc|dc|0.2|5天|3.39463|3.31526|3.36462|\n||nyc|dc|0.2|7天|3.38310|3.23292|3.31145|\n||nyc|dc|0.1|1天|3.77775|3.39991|3.28871|\n||nyc|dc|0.1|3天|3.53591|3.23931|3.37452|\n||nyc|dc|0.1|5天|3.39463|3.31526|3.33550|\n||nyc|dc|0.1|7天|3.38310|3.23292|3.30978|\n||nyc|dc|0.05|1天|3.77775|3.39991|3.33861|\n||nyc|dc|0.05|3天|3.53591|3.23931|3.41795|\n||nyc|dc|0.05|5天|3.39463|3.31526|3.32382|\n||nyc|dc|0.05|7天|3.38310|3.23292|3.23323|\n||nyc|dc|0.1|1天|3.77775|3.39991|3.41954|\n||nyc|dc|0.1|3天|3.53591|3.23931|3.25412|\n||nyc|dc|0.1|5天|3.39463|3.31526|3.25395|\n||nyc|dc|0.1|7天|3.38310|3.23292|3.24065|\n||nyc|dc|0.2|1天|3.77775|3.39991|3.41859|\n||nyc|dc|0.2|3天|3.53591|3.23931|3.24894|\n||nyc|dc|0.2|5天|3.39463|3.31526|3.23863|\n||nyc|dc|0.2|7天|3.38310|3.23292|3.24001|\n\n1. Correlation Graph 比 Distance Graph 更容易迁移\n2. 目标区域的数据质量可能会影响迁移效果\n3. transfer ratio可以相应做出调整，会影响迁移的效果\n\n新的实验：\n\n1. 在表格中加入graph类型\n2. 调整测试集长度、以调整目标区域训练数据到工作日区间\n\n| Graph |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: | :---------: |\n|C|nyc|chicago|0.3|1天|4.20614|3.95398|4.17578|\n|C|nyc|chicago|0.3|3天|3.96698|4.31441|4.26729|\n|C|nyc|chicago|0.3|5天|4.02681|3.58041|3.64260|\n|C|nyc|chicago|0.3|3天|3.96698|3.96458|3.98778|\n|nyc|dc|0.1|1天|3.63295|3.23437|4.71338|\n|nyc|dc|0.1|1天|3.63295|3.23437|4.70039|\n|nyc|dc|0.1|1天|3.63295|3.23437|4.70039|\n|nyc|dc|0.1|1天|3.63295|3.23437|3.90929|\n|C|nyc|dc|0.1|1天|3.63295|3.51374|3.53088|\n\n## Static Training Result\n\n1. val method: use 20% from training data\n2. test data length: about 30 days\n\n| Graph |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: | :---------: |\n|Correlation|nyc|chicago|0.1|1天|4.67712|**4.25955**|4.49069|\n|Correlation|nyc|chicago|0.1|3天|4.22121|3.85813|**3.68496**|\n|Correlation|nyc|chicago|0.1|5天|4.32650|**3.96839**|4.02760|\n|Correlation|nyc|chicago|0.1|7天|3.77726|**3.63063**|3.64774|\n|Correlation|nyc|dc|0.1|1天|3.77775|**3.23351**|3.30394|\n|Correlation|nyc|dc|0.1|3天|3.53591|**3.20542**|3.30849|\n|Correlation|nyc|dc|0.1|5天|3.39463|3.36513|**3.35833**|\n|Correlation|nyc|dc|0.1|7天|3.38310|**3.27965**|3.30015|\n|Correlation|dc|nyc|0.1|1天|9.42764|7.56931|**7.30441**|\n|Correlation|dc|nyc|0.1|3天|7.92233|**7.85794**|7.87110|\n|Correlation|dc|nyc|0.1|5天|7.87232|**7.78041**|7.86299|\n|Correlation|dc|nyc|0.1|7天|7.81039|~~11.09254~~|**7.80470**|\n|Correlation|dc|chicago|0.1|1天|10.58203|4.98520|**4.73672**|\n|Correlation|dc|chicago|0.1|3天|11.23320|4.55043|**4.06235**|\n|Correlation|dc|chicago|0.1|5天|9.93056|3.65179|**3.52144**|\n|Correlation|dc|chicago|0.1|7天|8.54751|4.09174|**3.94603**|\n|Correlation|chicago|nyc|0.1|1天|7.33929|7.12667|**7.10164**|\n|Correlation|chicago|nyc|0.1|3天|7.22262|6.92887|**6.81944**|\n|Correlation|chicago|nyc|0.1|5天|7.13852|**6.69150**|7.11825|\n|Correlation|chicago|nyc|0.1|7天|7.12167|**6.71981**|7.13281|\n|Correlation|chicago|dc|0.1|1天|3.78157|3.77235|**3.75456**|\n|Correlation|chicago|dc|0.1|3天|3.69740|**3.40131**|3.53313|\n|Correlation|chicago|dc|0.1|5天|3.62814|**3.13873**|3.16228|\n|Correlation|chicago|dc|0.1|7天|3.58433|**3.09991**|3.14930|\n\nProblem : 部分的Fine-tune结果，训练数据增加后，效果变差；迁移的效果不稳定；\n\n进行以下修改：\n\n1. reduce learning rate, to stable the training process，增加batch size\n2. 目前目前区域的训练数据大约在周三，以下调整到周五，这样保证大部分数据在工作日\n\n| Graph |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: | :---------: |\n|Correlation|nyc|chicago|0.3|1天|5.38677|4.94947|5.30289|\n|Correlation|nyc|chicago|0.3|3天|4.34201|3.86219|3.98421|\n|Correlation|nyc|chicago|0.3|5天|4.06206|3.82933|3.85310|\n|Correlation|nyc|chicago|0.3|7天|3.72066|3.60633|3.61164|\n|Correlation|nyc|dc|0.3|1天|4.38434|4.87484|4.98700|\n|Correlation|nyc|dc|0.3|3天|3.41225|3.57403|3.59285|\n|Correlation|nyc|dc|0.3|5天|3.44476|3.35405|3.30752|\n|Correlation|nyc|dc|0.3|7天|3.39200|3.37872|3.28680|\n|Correlation|dc|nyc|0.3|1天|8.34917|8.34650|18.33073|\n|Correlation|dc|nyc|0.3|3天|7.94347|7.88922|7.93095|\n|Correlation|dc|nyc|0.3|5天|7.90373|7.89213|7.90797|\n|Correlation|dc|nyc|0.3|7天|7.90058|7.87062|7.90461|\n|Correlation|dc|chicago|0.3|1天|10.86334|4.99778|5.94911|\n|Correlation|dc|chicago|0.3|3天|11.46182|5.25774|4.26376|\n|Correlation|dc|chicago|0.3|5天|10.17678|4.09519|3.56348|\n|Correlation|dc|chicago|0.3|7天|8.70574|5.25094|3.40993|\n|Correlation|chicago|nyc|0.3|1天|7.36875|7.47049|7.47635|\n|Correlation|chicago|nyc|0.3|3天|7.26527|7.25193|7.22621|\n|Correlation|chicago|nyc|0.3|5天|7.25791|7.23149|7.22586|\n\n\n| Graph |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: | :---------: |\n|Correlation|nyc|chicago|0.1|1天|5.38677|4.94947|5.30022|\n|Correlation|nyc|chicago|0.1|3天|4.34201|3.94191|4.13253|\n|Correlation|nyc|chicago|0.1|5天|4.06206|3.82461|3.94119|\n|Correlation|nyc|chicago|0.1|7天|3.72066|3.60703|3.60470|\n|Correlation|nyc|dc|0.1|1天|4.38434|4.87484|4.98315|\n|Correlation|nyc|dc|0.1|3天|3.41225|3.78044|3.42910|\n|Correlation|nyc|dc|0.1|5天|3.44476|3.33215|3.31266|\n|Correlation|nyc|dc|0.1|7天|3.39200|3.37359|3.26246|\n|Correlation|dc|nyc|0.1|1天|8.34917|8.34650|8.32973|\n|Correlation|dc|nyc|0.1|3天|7.94347|8.05051|7.94830|\n|Correlation|dc|nyc|0.1|5天|7.90373|7.90132|7.90560|\n|Correlation|dc|nyc|0.1|7天|7.90058|7.87989|7.90426|\n|Correlation|dc|chicago|0.1|1天|10.86334|4.99787|5.76370|\n|Correlation|dc|chicago|0.1|3天|11.46182|5.91710|4.59539|\n|Correlation|dc|chicago|0.1|5天|10.17678|4.44333|3.61311|\n|Correlation|dc|chicago|0.1|7天|8.70574|3.63362|3.45863|\n|Correlation|chicago|nyc|0.1|1天|7.36875|7.47049|7.45168|\n|Correlation|chicago|nyc|0.1|3天|7.26527|7.25407|8.32680|\n|Correlation|chicago|nyc|0.1|5天|7.25791|7.23103|7.25204|\n|Correlation|chicago|nyc|0.1|7天|7.24833|7.20168|7.23582|\n|Correlation|chicago|dc|0.1|1天|3.86311|4.60512|3.91758|\n|Correlation|chicago|dc|0.1|3天|3.66394|3.32028|3.61588|\n|Correlation|chicago|dc|0.1|5天|3.62543|3.52207|3.56268|\n|Correlation|chicago|dc|0.1|7天|3.59582|3.56239|3.53162|\n\n| Graph |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: | :---------: |\n|Correlation|nyc|chicago|0.05|1天|5.38677|4.94947|5.30021|\n|Correlation|nyc|chicago|0.05|3天|4.34201|4.21479|3.94523|\n|Correlation|nyc|chicago|0.05|5天|4.06206|3.84668|3.91428|\n|Correlation|nyc|chicago|0.05|7天|3.72066|3.62060|3.60362|\n|Correlation|nyc|dc|0.05|1天|4.38434|4.87484|4.98234|\n|Correlation|nyc|dc|0.05|3天|3.41225|3.51476|3.68511|\n|Correlation|nyc|dc|0.05|5天|3.44476|3.28846|3.34820|\n|Correlation|nyc|dc|0.05|7天|3.39200|3.37931|3.27885|\n|Correlation|dc|nyc|0.05|1天|8.34917|8.34650|8.33439|\n|Correlation|dc|nyc|0.05|3天|7.94347|7.58449|7.93117|\n|Correlation|dc|nyc|0.05|5天|7.90373|7.89797|7.90328|\n|Correlation|dc|nyc|0.05|7天|7.90058|7.89736|7.90086|\n|Correlation|dc|chicago|0.05|1天|10.86334|4.99778|5.82246|\n|Correlation|dc|chicago|0.05|3天|11.46182|5.09725|4.57277|\n|Correlation|dc|chicago|0.05|5天|10.17678|4.13495|3.85751|\n|Correlation|dc|chicago|0.05|7天|8.70574|3.61414|3.76792|\n|Correlation|chicago|nyc|0.05|1天|7.36875|7.47049|7.45205|\n|Correlation|chicago|nyc|0.05|3天|7.26527|7.25339|8.75825|\n|Correlation|chicago|nyc|0.05|5天|7.25791|7.23152|7.24569|\n|Correlation|chicago|nyc|0.05|7天|7.24833|7.19456|7.24255|\n|Correlation|chicago|dc|0.05|1天|3.86311|4.60512|3.89865|\n|Correlation|chicago|dc|0.05|3天|3.66394|3.48957|3.45902|\n|Correlation|chicago|dc|0.05|5天|3.62543|3.53435|3.55831|\n|Correlation|chicago|dc|0.05|7天|3.59582|3.50022|3.52657|\n\nChange Back to 周三 setting， and test other transfer ratio，change lr back to 0.0005\n\n| Graph |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: | :---------: |\n|Correlation|nyc|chicago|0.2|1天|4.67712|4.26000|4.37578|\n|Correlation|nyc|chicago|0.2|3天|4.22121|3.81024|4.21875|\n|Correlation|nyc|chicago|0.2|5天|4.32650|3.84399|3.93527|\n|Correlation|nyc|chicago|0.2|7天|3.77726|3.62769|3.65340|\n|Correlation|nyc|dc|0.2|1天|3.77775|3.23351|3.48805|\n|Correlation|nyc|dc|0.2|3天|3.53591|3.37679|3.35672|\n|Correlation|nyc|dc|0.2|5天|3.39463|3.28378|3.38352|\n|Correlation|nyc|dc|0.2|7天|3.38310|3.26814|3.30668|\n|Correlation|dc|nyc|0.2|1天|9.42764|7.56931|7.65780|\n|Correlation|dc|nyc|0.2|3天|7.92233|7.56916|7.85753|\n|Correlation|dc|nyc|0.2|5天|7.87232|7.80455|7.87182|\n|Correlation|dc|nyc|0.2|7天|7.81039|7.56197|7.81538|\n|Correlation|dc|chicago|0.2|1天|10.58203|4.98520|4.97218|\n|Correlation|dc|chicago|0.2|3天|11.23320|4.18053|3.68141|\n|Correlation|dc|chicago|0.2|5天|9.93056|3.62506|3.43282|\n|Correlation|dc|chicago|0.2|7天|8.54751|4.09224|3.36984|\n|Correlation|chicago|nyc|0.2|1天|7.33929|7.12667|7.08104|\n|Correlation|chicago|nyc|0.2|3天|7.22262|7.27643|6.83507|\n|Correlation|chicago|nyc|0.2|5天|7.13852|6.78991|7.12228|\n|Correlation|chicago|nyc|0.2|7天|7.12167|6.69170|7.12530|\n|Correlation|chicago|dc|0.2|1天|3.78157|3.77235|3.75854|\n|Correlation|chicago|dc|0.2|3天|3.69740|3.26502|3.50998|\n|Correlation|chicago|dc|0.2|5天|3.62814|3.13389|3.17730|\n|Correlation|chicago|dc|0.2|7天|3.58433|3.11130|3.16027|\n\nTake a smaller lr = 1e-5,\n\n| Graph |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: | :---------: |\n|Correlation|nyc|chicago|0.2|1天|4.67712|4.25025|4.48849|\n|Correlation|nyc|chicago|0.2|1天|4.67712|4.64628|4.38959|\n|Correlation|nyc|chicago|0.2|3天|4.22121|4.10957|3.88816|\n|Correlation|nyc|chicago|0.2|5天|4.32650|3.96755|4.01513|\n|Correlation|nyc|chicago|0.2|7天|3.77726|3.61148|3.63531|\n|Correlation|nyc|dc|0.2|1天|3.77775|3.41926|3.47251|\n|Correlation|nyc|dc|0.2|3天|3.53591|3.47903|3.28438|\n|Correlation|nyc|dc|0.2|5天|3.39463|3.32894|3.36384|\n|Correlation|nyc|dc|0.2|7天|3.38310|3.25412|3.25860|\n|Correlation|dc|nyc|0.2|1天|9.42764|7.24540|7.62634|\n|Correlation|dc|nyc|0.2|3天|7.92233|7.88247|7.84188|\n|Correlation|dc|nyc|0.2|5天|7.87232|7.75617|7.86730|\n|Correlation|dc|nyc|0.2|7天|7.81039|7.25333|7.78785|\n|Correlation|dc|chicago|0.2|1天|10.58203|5.07799|4.99096|\n|Correlation|dc|chicago|0.2|3天|11.23320|4.29366|3.70654|\n|Correlation|nyc|chicago|0.3|1天|4.67712|4.64628|4.45747|\n|Correlation|nyc|chicago|0.3|1天|4.67712|3.86177|4.00894|\n|Correlation|nyc|chicago|0.35|1天|4.67712|3.86177|4.01409|\n|Correlation|nyc|chicago|0.35|3天|4.22121|3.73511|3.91791|\n|Correlation|nyc|chicago|0.35|1天|4.67712|3.86177|4.01409|\n|Correlation|nyc|chicago|0.35|3天|4.22121|3.91369|3.82390|\n|Correlation|nyc|chicago|0.35|5天|4.32650|3.83038|4.13916|\n|Correlation|nyc|chicago|0.35|7天|3.77726|3.64188|3.68836|\n|Correlation|nyc|chicago|0.35|1天|4.67712|3.86177|4.01409|\n|Correlation|nyc|chicago|0.35|3天|4.22121|3.77503|3.80009|\n|Correlation|nyc|chicago|0.35|5天|4.32650|3.82202|3.90571|\n|Correlation|nyc|chicago|0.35|7天|3.77726|3.63230|3.68506|\n|Correlation|nyc|chicago|0.35|1天|4.67712|4.17959|4.33638|\n|Correlation|nyc|chicago|0.35|1天|4.67712|3.92269|4.00094|\n|Correlation|nyc|chicago|0.1|1天|4.67712|3.92269|3.98607|\n|Correlation|nyc|chicago|0.1|1天|4.67712|3.92269|3.98607|\n|Correlation|nyc|chicago|0.1|1天|4.67712|4.34035|4.44132|\n|Correlation|nyc|chicago|0.1|1天|4.67712|3.92269|3.98607|\n|Correlation|nyc|chicago|0.1|3天|4.22121|3.70477|3.79106|\n|Correlation|nyc|chicago|0.1|5天|4.32650|4.02529|4.07782|\n|Correlation|nyc|chicago|0.1|7天|3.77726|3.64502|3.64874|\n|Correlation|nyc|chicago|0.1|1天|4.67712|3.85330|3.94753|\n\n\n\n|    Graph    | Match        |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :---------: | ------------ | :-----: | :-----: | :------------: | :-------------: | :-------: | :-----: | :---------: |\n|Correlation|checkin|nyc|chicago|0.1|1天|4.67712|4.36085|3.98205|\n|Correlation|checkin|nyc|chicago|0.1|3天|4.22121|3.78306|3.72780|\n|Correlation|checkin|nyc|chicago|0.1|5天|4.32650|4.04593|4.03227|\n|Correlation|checkin|nyc|chicago|0.1|7天|3.77726|3.61688|3.61353|\n|Correlation|checkin|nyc|dc|0.1|1天|3.77775|3.26938|3.27214|\n|Correlation|checkin|nyc|dc|0.1|3天|3.53591|3.26024|3.23687|\n|Correlation|checkin|nyc|dc|0.1|5天|3.39463|3.38980|3.38501|\n|Correlation|checkin|nyc|dc|0.1|7天|3.38310|3.31886|3.30954|\n|Correlation|checkin|chicago|dc|0.1|1天|3.78157|3.70971|3.68627|\n|Correlation|checkin|chicago|dc|0.1|3天|3.69740|3.14678|3.16276|\n|Correlation|checkin|chicago|dc|0.1|5天|3.62814|3.16973|3.18279|\n|Correlation|checkin|chicago|dc|0.1|7天|3.58433|3.10981|3.14764|\n|Correlation|checkin|chicago|nyc|0.1|1天|7.33929|6.93074|6.98819|\n|Correlation|checkin|chicago|nyc|0.1|3天|7.22262|6.81888|6.78142|\n|Correlation|checkin|chicago|nyc|0.1|5天|7.13852|6.68927|7.10522|\n|Correlation|checkin|chicago|nyc|0.1|7天|7.12167|6.68495|7.10102|\n|Correlation|checkin|dc|nyc|0.1|1天|9.42764|7.58686|7.48810|\n|Correlation|checkin|dc|nyc|0.1|3天|7.92233|6.87626|7.59136|\n|Correlation|checkin|dc|nyc|0.1|5天|7.87232|7.68152|7.87473|\n|Correlation|checkin|dc|nyc|0.1|7天|7.81039|7.81719|7.80975|\n|Correlation|checkin|dc|chicago|0.1|1天|10.58203|4.79336|4.42591|\n|Correlation|checkin|dc|chicago|0.1|3天|11.23320|3.63033|3.59785|\n|Correlation|checkin|dc|chicago|0.1|5天|9.93056|4.27806|3.38808|\n|Correlation|checkin|dc|chicago|0.1|7天|8.54751|4.07764|3.38041|\n\n#### Dynamic training mode, other parameters are the same\n\n|    Graph    | Match        |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :---------: | ------------ | :-----: | :-----: | :------------: | :-------------: | :-------: | :-----: | :---------: |\n|Correlation|checkin|nyc|chicago|0.1|1天|4.67712|4.36085|3.98304|\n|Correlation|checkin|nyc|chicago|0.1|3天|4.22121|3.71737|3.71944|\n|Correlation|checkin|nyc|chicago|0.1|5天|4.32650|4.04136|4.12380|\n|Correlation|checkin|nyc|chicago|0.1|7天|3.77726|3.60159|3.61911|\n|Correlation|checkin|nyc|dc|0.1|1天|3.77775|3.26845|3.24397|\n|Correlation|checkin|nyc|dc|0.1|3天|3.53591|3.26197|3.23575|\n|Correlation|checkin|nyc|dc|0.1|5天|3.39463|3.40511|3.40644|\n|Correlation|checkin|nyc|dc|0.1|7天|3.38310|3.32217|3.33183|\n|Correlation|checkin|chicago|dc|0.1|1天|3.78157|3.70971|3.68629|\n|Correlation|checkin|chicago|dc|0.1|3天|3.69740|3.12705|3.15397|\n|Correlation|checkin|chicago|dc|0.1|5天|3.62814|3.16530|3.18082|\n|Correlation|checkin|chicago|dc|0.1|7天|3.58433|3.11014|3.15014|\n|Correlation|checkin|chicago|nyc|0.1|1天|7.33929|6.93074|6.98320|\n|Correlation|checkin|chicago|nyc|0.1|3天|7.22262|6.81979|6.79395|\n|Correlation|checkin|chicago|nyc|0.1|5天|7.13852|6.67125|7.15681|\n|Correlation|checkin|chicago|nyc|0.1|7天|7.12167|6.65707|7.09085|\n|Correlation|checkin|dc|nyc|0.1|1天|9.42764|7.58686|7.67655|\n|Correlation|checkin|dc|nyc|0.1|3天|7.92233|6.69994|9.09571|\n|Correlation|checkin|dc|nyc|0.1|5天|7.87232|7.65244|7.86764|\n|Correlation|checkin|dc|nyc|0.1|7天|7.81039|7.41190|7.80580|\n|Correlation|checkin|dc|chicago|0.1|1天|10.58203|4.79336|4.65393|\n|Correlation|checkin|dc|chicago|0.1|3天|11.23320|3.68010|4.08812|\n|Correlation|checkin|dc|chicago|0.1|5天|9.93056|3.95342|3.64199|\n|Correlation|checkin|dc|chicago|0.1|7天|8.54751|4.06561|3.93779|\n\n#### The same parameter, except a smaller lr\n\n|    Graph    | Match        |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :---------: | ------------ | :-----: | :-----: | :------------: | :-------------: | :-------: | :-----: | :---------: |\n|Correlation|checkin|nyc|chicago|0.1|1天|4.67712|3.92269|3.99061|\n|Correlation|checkin|nyc|chicago|0.1|3天|4.22121|3.71275|3.74433|\n|Correlation|checkin|nyc|chicago|0.1|5天|4.32650|3.87218|4.06787|\n|Correlation|checkin|nyc|chicago|0.1|7天|3.77726|3.62829|3.64411|\n|Correlation|checkin|nyc|dc|0.1|1天|3.77775|3.41202|3.24368|\n|Correlation|checkin|nyc|dc|0.1|3天|3.53591|3.23791|3.22884|\n|Correlation|checkin|nyc|dc|0.1|5天|3.39463|3.39410|3.39393|\n|Correlation|checkin|nyc|dc|0.1|7天|3.38310|3.23871|3.23573|\n|Correlation|checkin|chicago|dc|0.1|1天|3.78157|3.71789|3.69317|\n|Correlation|checkin|chicago|dc|0.1|3天|3.69740|3.13670|3.16728|\n|Correlation|checkin|chicago|dc|0.1|5天|3.62814|3.16764|3.18577|\n|Correlation|checkin|chicago|dc|0.1|7天|3.58433|3.11301|3.15291|\n|Correlation|checkin|chicago|nyc|0.1|1天|7.33929|6.90001|6.96449|\n|Correlation|checkin|chicago|nyc|0.1|3天|7.22262|6.79849|6.76211|\n|Correlation|checkin|chicago|nyc|0.1|5天|7.13852|6.69655|7.10062|\n|Correlation|checkin|chicago|nyc|0.1|7天|7.12167|6.69928|7.10788|\n|Correlation|checkin|dc|nyc|0.1|1天|9.42764|7.78120|7.75579|\n|Correlation|checkin|dc|nyc|0.1|3天|7.92233|6.91918|8.86747|\n|Correlation|checkin|dc|nyc|0.1|5天|7.87232|7.59995|7.87427|\n|Correlation|checkin|dc|nyc|0.1|7天|7.81039|7.43801|7.81107|\n|Correlation|checkin|dc|chicago|0.1|1天|10.58203|4.67753|4.75832|\n|Correlation|checkin|dc|chicago|0.1|3天|11.23320|4.37880|4.00140|\n|Correlation|checkin|dc|chicago|0.1|5天|9.93056|3.78431|3.73602|\n|Correlation|checkin|dc|chicago|0.1|7天|8.54751|4.07984|3.84819|\n\n## Experiment 1\n\nParameters"
  },
  {
    "path": "Experiments/STMeta_Transfer/transfer_result_overall.md",
    "content": "## Base experiment result\n\n#### Pre-train result\n\n|    Graph    |  City   | Result  |\n| :---------: | :-----: | :-----: |\n| Correlation |   NYC   | 7.00824 |\n| Correlation | Chicago | 3.29530 |\n| Correlation |   DC    | 2.86770 |\n|  Distance   |   NYC   | 7.96931 |\n|  Distance   | Chicago | 3.10245 |\n|  Distance   |   DC    | 3.78748 |\n\n#### Parameters (chosen by experiments)\n\n1. FT与Transfer，Validate数据 使用训练数据的30%，Test data 长度约为30天\n2. TD的训练数据为工作日（周三）\n3. 训练学习率 1e-5，early-stopping的测试长度为500-epoch （当lr较大时FT效果会很差，所以保持了比较小的值，lr对Transfer的影响不大）\n4. static training\n\n|    Graph    | Match        |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :---------: | ------------ | :-----: | :-----: | :------------: | :-------------: | :-------: | :-----: | :---------: |\n|Correlation|checkin|nyc|chicago|0.1|1天|4.67712|**3.92269**|3.99061|\n|Correlation|checkin|nyc|chicago|0.1|3天|4.22121|**3.71275**|3.74433|\n|Correlation|checkin|nyc|chicago|0.1|5天|4.32650|**3.87218**|4.06787|\n|Correlation|checkin|nyc|chicago|0.1|7天|3.77726|**3.62829**|3.64411|\n|Correlation|checkin|nyc|dc|0.1|1天|3.77775|3.41202|**3.24368**|\n|Correlation|checkin|nyc|dc|0.1|3天|3.53591|3.23791|**3.22884**|\n|Correlation|checkin|nyc|dc|0.1|5天|3.39463|3.39410|**3.39393**|\n|Correlation|checkin|nyc|dc|0.1|7天|3.38310|3.23871|**3.23573**|\n|Correlation|checkin|chicago|dc|0.1|1天|3.78157|3.71789|**3.69317**|\n|Correlation|checkin|chicago|dc|0.1|3天|3.69740|**3.13670**|3.16728|\n|Correlation|checkin|chicago|dc|0.1|5天|3.62814|**3.16764**|3.18577|\n|Correlation|checkin|chicago|dc|0.1|7天|3.58433|**3.11301**|3.15291|\n|Correlation|checkin|chicago|nyc|0.1|1天|7.33929|**6.90001**|6.96449|\n|Correlation|checkin|chicago|nyc|0.1|3天|7.22262|6.79849|**6.76211**|\n|Correlation|checkin|chicago|nyc|0.1|5天|7.13852|**6.69655**|7.10062|\n|Correlation|checkin|chicago|nyc|0.1|7天|7.12167|**6.69928**|7.10788|\n|Correlation|checkin|dc|nyc|0.1|1天|9.42764|7.78120|**7.75579**|\n|Correlation|checkin|dc|nyc|0.1|3天|7.92233|**6.91918**|8.86747|\n|Correlation|checkin|dc|nyc|0.1|5天|7.87232|**7.59995**|7.87427|\n|Correlation|checkin|dc|nyc|0.1|7天|7.81039|**7.43801**|7.81107|\n|Correlation|checkin|dc|chicago|0.1|1天|10.58203|**4.67753**|4.75832|\n|Correlation|checkin|dc|chicago|0.1|3天|11.23320|4.37880|**4.00140**|\n|Correlation|checkin|dc|chicago|0.1|5天|9.93056|3.78431|**3.73602**|\n|Correlation|checkin|dc|chicago|0.1|7天|8.54751|4.07984|**3.84819**|\n\n|    Graph    | Match        |   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :---------: | ------------ | :-----: | :-----: | :------------: | :-------------: | :-------: | :-----: | :---------: |\n|Distance|checkin|nyc|chicago|0.1|1天|4.70441|**4.70361**|12.59841|\n|Distance|checkin|nyc|chicago|0.1|3天|4.70441|4.82347|4.78770|\n|Distance|checkin|nyc|chicago|0.1|5天|**4.70441**|4.83354|4.81036|\n|Distance|checkin|nyc|chicago|0.1|7天|4.70441|**4.70070**|4.74429|\n|Distance|checkin|nyc|dc|0.1|1天|4.18998|**4.18815**|4.18669|\n|Distance|checkin|nyc|dc|0.1|3天|4.18998|3.95583|**3.95511**|\n|Distance|checkin|nyc|dc|0.1|5天|4.18998|**3.96894**|4.01603|\n|Distance|checkin|chicago|dc|0.1|1天|3.19900|**3.10418**|3.11494|\n|Distance|checkin|chicago|dc|0.1|3天|3.19900|**3.00662**|3.13352|\n|Distance|checkin|chicago|dc|0.1|5天|3.19900|**2.98474**|2.99215|\n|Distance|checkin|chicago|dc|0.1|7天|3.19900|**2.89581**|2.94413|\n|Distance|checkin|chicago|nyc|0.1|1天|10.24455|**9.44282**|12.85142|\n|Distance|checkin|chicago|nyc|0.1|3天|10.24455|**6.87987**|12.93270|\n|Distance|checkin|chicago|nyc|0.1|5天|10.24455|**10.21737**|13.56898|\n|Distance|checkin|chicago|nyc|0.1|7天|10.24455|**6.66069**|12.12317|\n|Distance|checkin|dc|nyc|0.1|1天|7.23524|7.23436|**7.23350**|\n|Distance|checkin|dc|nyc|0.1|3天|7.23524|**6.73650**|6.81929|\n|Distance|checkin|dc|nyc|0.1|5天|7.23524|**7.23440**|7.23744|\n|Distance|checkin|dc|nyc|0.1|7天|**7.23524**|7.23836|7.23745|\n|Distance|checkin|dc|chicago|0.1|1天|**4.34642**|4.35396|4.34736|\n|Distance|checkin|dc|chicago|0.1|5天|**4.34642**|4.49737|4.39714|\n|Distance|checkin|dc|chicago|0.1|7天|**4.34642**|4.49232|4.37209|\n|Distance|checkin|dc|chicago|0.1|3天|**4.34642**|4.46849|4.47618|\n\n总结\n\n1. Correlation graph 的迁移效果比 Distance graph 好\n2. 迁移效果较明显的是：NYC => DC，DC => Chicago\n\n## Tuning match methods\n\ntransfer ratio = 0.1，graph = Correlation，其余参数与上一节列出的相同\n\n以下为使用不用match方法进行匹配的迁移结果，结果展示以迁移方向为组、每组内包含4种相似站点匹配方法，加粗的是目标区域有1天3天的情况下，迁移结果rmse最小的匹配方法\n\n1. checkin 匹配方法：使用站点附近1km、工作日与节假日的checkin特征进行匹配\n2. poi 匹配方法：使用站点附近1km的poi特征进行匹配\n3. traffic：使用目标区域训练数据进行匹配\n4. fake_traffic：在目标区域使用一个月流量数据进行匹配，训练数据、测试数据保持与其他实验一致\n\n|      Match       |   SD    |   TD    | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :--------------: | :-----: | :-----: | :-------------: | :-------: | :-----: | :---------: |\n|     checkin      |   nyc   | chicago |       1天       |  4.76519  | 3.91775 |   4.00033   |\n|     checkin      |   nyc   | chicago |       3天       |  4.21627  | 3.71755 |   3.73617   |\n|     **poi**      |   nyc   | chicago |     **1天**     |  4.76519  | 3.91775 | **3.99740** |\n|     **poi**      |   nyc   | chicago |     **3天**     |  4.21627  | 3.71755 | **3.71152** |\n|     traffic      |   nyc   | chicago |       1天       |  4.76519  | 3.91775 |   3.99903   |\n|     traffic      |   nyc   | chicago |       3天       |  4.21627  | 3.71755 |   3.71532   |\n|   fake_traffic   |   nyc   | chicago |       1天       |  4.76519  | 3.91775 |   4.01753   |\n|   fake_traffic   |   nyc   | chicago |       3天       |  4.21627  | 3.71755 |   3.71876   |\n|     checkin      |   nyc   |   dc    |       1天       |  3.77953  | 3.40948 |   3.27021   |\n|     checkin      |   nyc   |   dc    |       3天       |  3.53572  | 3.24863 |   3.22698   |\n|       poi        |   nyc   |   dc    |       1天       |  3.77953  | 3.40948 |   3.26955   |\n|       poi        |   nyc   |   dc    |       3天       |  3.53572  | 3.24863 |   3.23642   |\n|     traffic      |   nyc   |   dc    |       1天       |  3.77953  | 3.40948 |   3.27314   |\n|     traffic      |   nyc   |   dc    |       3天       |  3.53572  | 3.24863 |   3.24170   |\n| **fake_traffic** |   nyc   |   dc    |     **1天**     |  3.77953  | 3.40948 | **3.25348** |\n| **fake_traffic** |   nyc   |   dc    |     **3天**     |  3.53572  | 3.24863 | **3.23603** |\n|     checkin      | chicago |   dc    |       1天       |  3.78083  | 3.71714 |   3.69250   |\n|   **checkin**    | chicago |   dc    |     **3天**     |  3.69748  | 3.15200 | **3.15129** |\n|     **poi**      | chicago |   dc    |     **1天**     |  3.78083  | 3.71714 | **3.69245** |\n|       poi        | chicago |   dc    |       3天       |  3.69748  | 3.15200 |   3.16164   |\n|     traffic      | chicago |   dc    |       1天       |  3.78083  | 3.71714 |   3.68980   |\n|     traffic      | chicago |   dc    |       3天       |  3.69748  | 3.15200 |   3.18018   |\n|   fake_traffic   | chicago |   dc    |       1天       |  3.78083  | 3.71714 |   3.70910   |\n|   fake_traffic   | chicago |   dc    |       3天       |  3.69748  | 3.15200 |   3.20673   |\n|     checkin      | chicago |   nyc   |       1天       |  7.33863  | 6.90045 |   6.96378   |\n|   **checkin**    | chicago |   nyc   |     **3天**     |  7.22249  | 6.83481 | **6.77691** |\n|       poi        | chicago |   nyc   |       1天       |  7.33863  | 6.90045 |   6.94736   |\n|       poi        | chicago |   nyc   |       3天       |  7.22249  | 6.83481 |   6.80737   |\n|     traffic      | chicago |   nyc   |       1天       |  7.33863  | 6.90045 |   6.96541   |\n|     traffic      | chicago |   nyc   |       3天       |  7.22249  | 7.00043 |   7.78913   |\n| **fake_traffic** | chicago |   nyc   |     **1天**     |  7.33863  | 6.90045 | **6.94016** |\n|   fake_traffic   | chicago |   nyc   |       3天       |  7.22249  | 6.83481 |   6.81975   |\n|   **checkin**    |   dc    |   nyc   |     **1天**     |  9.38367  | 7.77615 | **7.49206** |\n|   **checkin**    |   dc    |   nyc   |     **3天**     |  7.92180  | 6.93686 | **7.64479** |\n|       poi        |   dc    |   nyc   |       1天       |  9.38367  | 7.77615 |   7.54143   |\n|       poi        |   dc    |   nyc   |       3天       |  7.92180  | 6.93686 |   7.92671   |\n|     traffic      |   dc    |   nyc   |       1天       |  9.38367  | 7.77615 |   7.58968   |\n|     traffic      |   dc    |   nyc   |       3天       |  7.92180  | 6.93686 |   8.59754   |\n|   fake_traffic   |   dc    |   nyc   |       1天       |  9.38367  | 7.77615 |   7.72215   |\n|   fake_traffic   |   dc    |   nyc   |       3天       |  7.92180  | 6.93686 |   9.24880   |\n|     checkin      |   dc    | chicago |       1天       | 10.60726  | 4.71315 |   4.52085   |\n|   **checkin**    |   dc    | chicago |     **3天**     | 11.21222  | 3.79817 | **3.58828** |\n|     **poi**      |   dc    | chicago |     **1天**     | 10.60726  | 4.71315 | **4.48266** |\n|       poi        |   dc    | chicago |       3天       | 11.21222  | 3.79817 |   3.81154   |\n|     traffic      |   dc    | chicago |       1天       | 10.60726  | 4.71315 |   4.52752   |\n|     traffic      |   dc    | chicago |       3天       | 11.21222  | 3.79817 |   3.64937   |\n|   fake_traffic   |   dc    | chicago |       1天       | 10.60726  | 4.71315 |   4.70475   |\n|   fake_traffic   |   dc    | chicago |       3天       | 11.21222  | 3.79817 |   3.67280   |\n\n## Tuning  transfer mode\n\ngraph：correlation，transfer ratio：0.1，match-method：checkin\n\n| TrainMode |   SD    |   TD    | TD-训练样本数量 | TD-Direct |  TD-FT  | TD-Transfer |\n| :-------: | :-----: | :-----: | :-------------: | :-------: | :-----: | :---------: |\n|  dynamic  |   nyc   | chicago |       1天       |  4.67712  | 3.92269 |   3.99061   |\n|  static   |   nyc   | chicago |       1天       |  4.67712  | 3.92269 |   3.99061   |\n|  dynamic  |   nyc   | chicago |       3天       |  4.22121  | 3.72731 |   3.72169   |\n|  static   |   nyc   | chicago |       3天       |  4.22121  | 3.72731 |   3.74433   |\n|  dynamic  |   nyc   | chicago |       5天       |  4.32650  | 4.03527 |   4.09383   |\n|  static   |   nyc   | chicago |       5天       |  4.32650  | 4.03527 |   4.06787   |\n|  dynamic  |   nyc   | chicago |       7天       |  3.77726  | 3.62886 |   3.64174   |\n|  static   |   nyc   | chicago |       7天       |  3.77726  | 3.62886 |   3.64411   |\n|  dynamic  |   nyc   |   dc    |       1天       |  3.77775  | 3.41219 |   3.24365   |\n|  static   |   nyc   |   dc    |       1天       |  3.77775  | 3.41219 |   3.24368   |\n|  dynamic  |   nyc   |   dc    |       3天       |  3.53591  | 3.24496 |   3.23717   |\n|  static   |   nyc   |   dc    |       3天       |  3.53591  | 3.24496 |   3.22884   |\n|  dynamic  |   nyc   |   dc    |       5天       |  3.39463  | 3.39877 |   3.41054   |\n|  static   |   nyc   |   dc    |       5天       |  3.39463  | 3.39877 |   3.39393   |\n|  dynamic  |   nyc   |   dc    |       7天       |  3.38310  | 3.29157 |   3.27758   |\n|  static   |   nyc   |   dc    |       7天       |  3.38310  | 3.29157 |   3.23573   |\n|  dynamic  | chicago |   dc    |       1天       |  3.78157  | 3.71789 |   3.69317   |\n|  static   | chicago |   dc    |       1天       |  3.78157  | 3.71789 |   3.69317   |\n|  dynamic  | chicago |   dc    |       3天       |  3.69740  | 3.14631 |   3.18608   |\n|  static   | chicago |   dc    |       3天       |  3.69740  | 3.14631 |   3.16728   |\n|  dynamic  | chicago |   dc    |       5天       |  3.62814  | 3.17078 |   3.19249   |\n|  static   | chicago |   dc    |       5天       |  3.62814  | 3.17078 |   3.18577   |\n|  dynamic  | chicago |   dc    |       7天       |  3.58433  | 3.11549 |   3.15131   |\n|  static   | chicago |   dc    |       7天       |  3.58433  | 3.11549 |   3.15291   |\n|  dynamic  | chicago |   nyc   |       1天       |  7.33929  | 7.38597 |   6.96449   |\n|  static   | chicago |   nyc   |       1天       |  7.33929  | 7.38597 |   6.96449   |\n|  dynamic  | chicago |   nyc   |       3天       |  7.55972  | 6.80038 |   6.77189   |\n|  static   | chicago |   nyc   |       3天       |  7.22262  | 6.80038 |   6.76211   |\n|  dynamic  | chicago |   nyc   |       5天       |  7.13852  | 6.68604 |   7.10314   |\n|  static   | chicago |   nyc   |       5天       |  7.13852  | 6.68604 |   7.10062   |\n|  dynamic  | chicago |   nyc   |       7天       |  7.12167  | 6.67103 |   7.09394   |\n|  static   | chicago |   nyc   |       7天       |  7.12167  | 6.67103 |   7.10788   |\n|  dynamic  |   dc    |   nyc   |       1天       |  9.41977  | 7.78120 |   7.75578   |\n|  static   |   dc    |   nyc   |       1天       |  9.42764  | 7.78120 |   7.75579   |\n|  dynamic  |   dc    |   nyc   |       3天       |  7.92233  | 6.93770 |   8.94962   |\n|  static   |   dc    |   nyc   |       3天       |  7.92233  | 6.93770 |   8.86747   |\n|  dynamic  |   dc    |   nyc   |       5天       |  7.87232  | 7.67169 |   7.87556   |\n|  static   |   dc    |   nyc   |       5天       |  7.87232  | 7.67169 |   7.87427   |\n|  dynamic  |   dc    |   nyc   |       7天       | 24.38127  | 7.73380 |   7.81032   |\n|  static   |   dc    |   nyc   |       7天       |  7.81039  | 7.73380 |   7.81107   |\n|  dynamic  |   dc    | chicago |       1天       | 10.58203  | 4.67799 |   4.75832   |\n|  static   |   dc    | chicago |       1天       | 10.58203  | 4.67799 |   4.75832   |\n|  dynamic  |   dc    | chicago |       3天       | 11.23320  | 3.82442 |   4.21488   |\n|  static   |   dc    | chicago |       3天       | 11.23320  | 3.82442 |   4.00140   |\n|  dynamic  |   dc    | chicago |       5天       |  9.93056  | 3.79295 |   3.91066   |\n|  static   |   dc    | chicago |       5天       |  9.93056  | 3.79295 |   3.73602   |\n|  dynamic  |   dc    | chicago |       7天       |  8.54751  | 4.08669 |   3.75169   |\n|  static   |   dc    | chicago |       7天       |  8.54751  | 4.08669 |   3.84819   |\n\ndynamic 和 static 训练方式的结果非常相近\n\n"
  },
  {
    "path": "Experiments/STMeta_Transfer/使用流量匹配的结果.md",
    "content": "|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|chicago|dc|0.1|1天|6.11280|4.55692|5.37215|\n|chicago|dc|0.1|3天|6.11280|3.78414|3.81444|\n|chicago|dc|0.1|5天|6.11280|**3.71387**|**3.57140**|\n|chicago|dc|0.1|7天|6.11280|3.49791|3.51290|\n|chicago|nyc|0.1|1天|7.48254|6.18791|8.40362|\n|chicago|nyc|0.1|3天|7.48254|5.56169|6.23681|\n|chicago|nyc|0.1|5天|7.48254|**5.50264**|**5.48796**|\n|chicago|nyc|0.1|7天|7.48254|5.35242|5.92388|\n|nyc|dc|0.1|1天|6.38149|4.81328|5.37936|\n|nyc|dc|0.1|3天|6.38149|**4.29883**|**4.02823**|\n|nyc|dc|0.1|5天|6.38149|**4.00461**|**3.73410**|\n|nyc|dc|0.1|7天|6.38149|**3.88247**|**3.53777**|\n|nyc|chicago|0.1|1天|5.17356|4.43069|14.60072|\n|nyc|chicago|0.1|3天|5.17356|3.91972|4.51760|\n|nyc|chicago|0.1|5天|5.17356|3.92226|3.99908|\n|nyc|chicago|0.1|7天|5.17356|3.45871|3.52070|\n|dc|nyc|0.1|1天|5.63698|5.71627|7.50844|\n|dc|nyc|0.1|3天|5.63698|5.04235|6.39228|\n|dc|nyc|0.1|5天|5.63698|4.96078|5.12413|\n|dc|nyc|0.1|7天|5.63698|5.18230|7.22713|\n|dc|chicago|0.1|1天|3.65903|3.67704|16.17866|\n|dc|chicago|0.1|3天|3.65903|3.41615|4.15128|\n|dc|chicago|0.1|5天|3.65903|3.31678|3.84397|\n|dc|chicago|0.1|7天|3.65903|3.16704|3.36059|\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|chicago|dc|0.2|1天|6.11280|4.55692|7.24652|\n|chicago|dc|0.2|3天|6.11280|3.77025|3.93426|\n|chicago|dc|0.2|5天|6.11280|**3.72076**|**3.52238**|\n|chicago|dc|0.2|7天|6.11280|3.43305|3.49163|\n|chicago|nyc|0.2|1天|7.48254|6.18791|9.09922|\n|chicago|nyc|0.2|3天|7.48254|5.56620|6.04531|\n|chicago|nyc|0.2|5天|7.48254|5.56138|5.59693|\n|chicago|nyc|0.2|7天|7.48254|5.35215|6.20211|\n|nyc|dc|0.2|1天|6.38149|4.81328|5.29455|\n|nyc|dc|0.2|3天|6.38149|**4.29698**|**3.83532**|\n|nyc|dc|0.2|5天|6.38149|**4.08979**|**3.61762**|\n|nyc|dc|0.2|7天|6.38149|**3.89675**|**3.67976**|\n|nyc|chicago|0.2|1天|5.17356|4.43069|15.62595|\n|nyc|chicago|0.2|3天|5.17356|3.93514|4.67204|\n|nyc|chicago|0.2|5天|5.17356|3.88190|4.33452|\n|nyc|chicago|0.2|7天|5.17356|3.45361|3.78910|\n|dc|nyc|0.2|1天|5.63698|5.71626|7.73169|\n|dc|nyc|0.2|3天|5.63698|5.10009|6.30672|\n|dc|nyc|0.2|5天|5.63698|4.94753|7.74069|\n|dc|nyc|0.2|7天|5.63698|5.18979|6.65170|\n|dc|chicago|0.2|1天|3.65903|3.67704|48.02328|\n|dc|chicago|0.2|3天|3.65903|3.39926|4.60224|\n|dc|chicago|0.2|5天|3.65903|3.33136|3.97555|\n|dc|chicago|0.2|7天|3.65903|3.17461|3.50247|\n|chicago|nyc|0.2|1天|7.47502|6.17946|9.09478|\n|chicago|nyc|0.2|1天|9.09922|\n\n#### Using the new matching method\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|chicago|nyc|0.1|1天|7.48254|6.19588|8.59100|\n|chicago|nyc|0.1|3天|7.48254|5.58993|5.92595|\n|chicago|nyc|0.1|5天|7.48254|5.56601|5.60408|\n|chicago|nyc|0.1|7天|7.48254|5.39456|6.02994|\n|nyc|chicago|0.1|1天|5.17356|4.43069|15.76462|\n|nyc|chicago|0.1|3天|5.17356|3.94628|4.71117|\n|nyc|chicago|0.1|5天|5.17356|3.93868|4.47675|\n|nyc|chicago|0.1|7天|5.17356|3.46738|3.44430|\n|chicago|dc|0.1|1天|4.32390|3.87629|6.31661|\n|chicago|dc|0.1|3天|4.32390|5.21747|4.30885|\n|chicago|dc|0.1|5天|4.32390|3.25962|3.34276|\n|dc|nyc|0.1|1天|5.35244|5.15155|11.32685|\n|dc|nyc|0.1|3天|5.35244|4.83186|5.55304|\n|dc|nyc|0.1|5天|5.35244|4.79484|4.88849|\n|dc|nyc|0.1|7天|5.35244|4.83927|5.12925|\n|dc|nyc|0.1|1天|5.35244|5.15155|11.32685|\n"
  },
  {
    "path": "Experiments/STSGCN/Runner.py",
    "content": "import os\n# #############################################\n# # BenchMark Bike\n# #############################################\n# ########### NYC ########### --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\n# os.system(\"python STSGCN.py --dataset Bike --city NYC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ././config/PEMS03/STMeta_emb.json\")\n\n# # os.system(\"python STSGCN.py --dataset Bike --city NYC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ././config/PEMS03/STMeta_emb.json\")\n\n# os.system(\"python STSGCN.py --dataset Bike --city NYC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ././config/PEMS03/STMeta_emb.json\")\n\n\n# # # ########### Chicago ###########\n# # # # os.system(\"python STSGCN.py --dataset Bike --city Chicago --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ././config/PEMS03/STMeta_emb.json\")\n\n# # # # os.system(\"python STSGCN.py --dataset Bike --city Chicago --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# os.system(\"python STSGCN.py --dataset Bike --city Chicago --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n\n# # # ########### DC ###########\n# # # # os.system(\"python STSGCN.py --dataset Bike --city DC --data_range 0.25 --train_data_length 91 --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# # # # os.system(\"python STSGCN.py --dataset Bike --city DC --data_range 0.5 --train_data_length 183 --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# os.system(\"python STSGCN.py --dataset Bike --city DC --data_range all --train_data_length 365 --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n\n\n# # # ###############################################\n# # # # BenchMark DiDi\n# # # ###############################################\n# # # ############# Xian #############\n# # # # os.system(\"python STSGCN.py --dataset DiDi --city Xian --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# # # # os.system(\"python STSGCN.py --dataset DiDi --city Xian --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# os.system(\"python STSGCN.py --dataset DiDi --city Xian --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n\n\n# # # # ############# Chengdu #############\n# # # # # os.system(\"python STSGCN.py --dataset DiDi --city Chengdu --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# # # # # os.system(\"python STSGCN.py --dataset DiDi --city Chengdu --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# os.system(\"python STSGCN.py --dataset DiDi --city Chengdu --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config config/PEMS03/STMeta_emb_1.json\")\n\n\n\n# # # # ###############################################\n# # # # # BenchMark Metro\n# # # # ###############################################\n# # # # ############# Chongqing #############\n# # # # # os.system(\"python STSGCN.py --dataset Metro --city Chongqing --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# # # # # os.system(\"python STSGCN.py --dataset Metro --city Chongqing --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# os.system(\"python STSGCN.py --dataset Metro --city Chongqing --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n\n# # # # ############# Shanghai #############\n# # # # # os.system(\"python STSGCN.py --dataset Metro --city Shanghai --MergeIndex 3 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# # # # # os.system(\"python STSGCN.py --dataset Metro --city Shanghai --MergeIndex 6 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# os.system(\"python STSGCN.py --dataset Metro --city Shanghai --MergeIndex 12 --MergeWay sum --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb_1.json\")\n\n\n\n# # ###############################################\n# # # BenchMark ChargeStation\n# # ###############################################\n\n# # # os.system(\"python STSGCN.py --dataset ChargeStation --city Beijing --MergeIndex 1 --MergeWay max --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# os.system(\"python STSGCN.py --dataset ChargeStation --city Beijing --MergeIndex 2 --MergeWay max --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n\n\n# # # ###############################################\n# # # # BenchMark METR-LA\n# # # ###############################################\n\n# # # # os.system(\"python STSGCN.py --dataset METR --city LA --MergeIndex 3 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# # # # os.system(\"python STSGCN.py --dataset METR --city LA --MergeIndex 6 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# os.system(\"python STSGCN.py --dataset METR --city LA --MergeIndex 12 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n\n# # ###############################################\n# # # BenchMark PEMS-BAY\n# # ###############################################\n# # # os.system(\"python STSGCN.py --dataset PEMS --city BAY --MergeIndex 3 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# # # os.system(\"python STSGCN.py --dataset PEMS --city BAY --MergeIndex 6 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n# os.system(\"python STSGCN.py --dataset PEMS --city BAY --MergeIndex 12 --MergeWay average --closeness_len 12 --period_len 0 --trend_len 0 --config ./config/PEMS03/STMeta_emb.json\")\n\n\n"
  },
  {
    "path": "Experiments/STSGCN/STSGCN.py",
    "content": "import json\nimport argparse\nimport mxnet as mx\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model.STSGCN import *\nfrom UCTB.utils.utils_STSGCN import *\n\n#args\nparser = argparse.ArgumentParser()\nparser.add_argument(\"--config\", type=str,\n                    default='./config/PEMS03/STMeta_emb.json', help='configuration file')\nparser.add_argument(\"--test\", action=\"store_true\", help=\"test program\")\nparser.add_argument(\"--plot\", help=\"plot network graph\", action=\"store_true\")\nparser.add_argument(\"--save\", type=bool, default=True, help=\"save model\")\n\n# data loader parameters\nparser.add_argument(\"--dataset\", default='Bike', type=str,\n                    help=\"configuration file path\")\nparser.add_argument(\"--city\", default='NYC', type=str)\nparser.add_argument(\"--closeness_len\", default=6, type=int)\nparser.add_argument(\"--period_len\", default=7, type=int)\nparser.add_argument(\"--trend_len\", default=4, type=int)\nparser.add_argument(\"--data_range\", default=\"all\", type=str)\nparser.add_argument(\"--train_data_length\", default=\"all\", type=str)\nparser.add_argument(\"--test_ratio\", default=0.1, type=float)\nparser.add_argument(\"--MergeIndex\", default=1, type=int)\nparser.add_argument(\"--MergeWay\", default=\"sum\", type=str)\nparser.add_argument(\"--normalize\", default=False, type=bool)\nargs = parser.parse_args()\nconfig_filename = args.config\n\n#config\nwith open(config_filename, 'r') as f:\n    config = json.loads(f.read())\nbatch_size = config['batch_size']\nif isinstance(config['ctx'], list):\n    ctx = [mx.gpu(i) for i in config['ctx']]\nelif isinstance(config['ctx'], int):\n    ctx = mx.gpu(config['ctx'])\n\n#date_load\ndata_loader = NodeTrafficLoader(dataset=args.dataset, city=args.city,\n                                data_range=args.data_range, train_data_length=args.train_data_length,\n                                test_ratio=float(args.test_ratio),\n                                closeness_len=args.closeness_len,\n                                period_len=args.period_len,\n                                trend_len=args.trend_len,\n                                normalize=args.normalize,\n                                MergeIndex=args.MergeIndex,\n                                MergeWay=args.MergeWay)\n\n#config_params\nmodel_name, epochs, metric, mod, train_loader, val_loader, test_loader, normalizer, val_y, test_y, all_info = configData(\n    args, data_loader, batch_size, config, ctx)\n\n\n#Train Or Test\nif args.test:\n    epochs = 5\ntraining(epochs, metric, mod, train_loader, val_loader,\n         test_loader, normalizer, val_y, test_y, all_info)\n\n\n#Print result\nthe_best = min(all_info, key=lambda x: x[2])\nprint('Last Epoch : {}\\ntraining loss: {:.2f}\\nvalidation loss: {:.2f}\\n'\n      'testing: MAPE: {:.2f}\\n'\n      'testing: RMSE: {:.2f}\\n'.format(*the_best))\n\n#model_save\nif args.save:\n    mod.save_checkpoint(model_name, epochs)\n"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS03/STMeta_emb.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"GLU\",\n    \"temporal_emb\": true,\n    \"spatial_emb\": true,\n    \"use_mask\": true,\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"optimizer\": \"adam\",\n    \"learning_rate\": 1e-3,\n    \"epochs\": 1000,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS03/PEMS03.csv\",\n    \"id_filename\": \"data/PEMS03/PEMS03.txt\",\n    \"graph_signal_matrix_filename\": \"data/PEMS03/PEMS03.npz\",\n    \"num_of_vertices\": 358,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 1,\n    \"num_of_features\": 1\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS03/STMeta_emb_1.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"GLU\",\n    \"temporal_emb\": true,\n    \"spatial_emb\": true,\n    \"use_mask\": true,\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"optimizer\": \"adam\",\n    \"learning_rate\": 1e-3,\n    \"epochs\": 1000,\n    \"max_update_factor\": 1,\n    \"ctx\": 1,\n    \"adj_filename\": \"data/PEMS03/PEMS03.csv\",\n    \"id_filename\": \"data/PEMS03/PEMS03.txt\",\n    \"graph_signal_matrix_filename\": \"data/PEMS03/PEMS03.npz\",\n    \"num_of_vertices\": 358,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 1,\n    \"num_of_features\": 1\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS03/individual_GLU_mask_emb.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"GLU\",\n    \"temporal_emb\": true,\n    \"spatial_emb\": true,\n    \"use_mask\": true,\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"optimizer\": \"adam\",\n    \"learning_rate\": 1e-3,\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS03/PEMS03.csv\",\n    \"id_filename\": \"data/PEMS03/PEMS03.txt\",\n    \"graph_signal_matrix_filename\": \"data/PEMS03/PEMS03.npz\",\n    \"num_of_vertices\": 358,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12,\n    \"num_of_features\": 1\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS03/individual_GLU_nomask_emb.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"GLU\",\n    \"temporal_emb\": true,\n    \"spatial_emb\": true,\n    \"use_mask\": false,\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"learning_rate\": 1e-3,\n    \"optimizer\": \"adam\",\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS03/PEMS03.csv\",\n    \"id_filename\": \"data/PEMS03/PEMS03.txt\",\n    \"graph_signal_matrix_filename\": \"data/PEMS03/PEMS03.npz\",\n    \"num_of_vertices\": 358,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12,\n    \"num_of_features\": 1\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS03/individual_GLU_nomask_noemb.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"GLU\",\n    \"temporal_emb\": false,\n    \"spatial_emb\": false,\n    \"use_mask\": false,\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"learning_rate\": 1e-3,\n    \"optimizer\": \"adam\",\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS03/PEMS03.csv\",\n    \"id_filename\": \"data/PEMS03/PEMS03.txt\",\n    \"graph_signal_matrix_filename\": \"data/PEMS03/PEMS03.npz\",\n    \"num_of_vertices\": 358,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12,\n    \"num_of_features\": 1\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS03/individual_relu_nomask_noemb.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"relu\",\n    \"temporal_emb\": false,\n    \"spatial_emb\": false,\n    \"use_mask\": false,\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"learning_rate\": 1e-3,\n    \"optimizer\": \"adam\",\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS03/PEMS03.csv\",\n    \"id_filename\": \"data/PEMS03/PEMS03.txt\",\n    \"graph_signal_matrix_filename\": \"data/PEMS03/PEMS03.npz\",\n    \"num_of_vertices\": 358,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12,\n    \"num_of_features\": 1\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS03/sharing_relu_nomask_noemb.json",
    "content": "{\n    \"module_type\": \"sharing\",\n    \"act_type\": \"relu\",\n    \"temporal_emb\": false,\n    \"spatial_emb\": false,\n    \"use_mask\": false,\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"learning_rate\": 1e-3,\n    \"optimizer\": \"adam\",\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS03/PEMS03.csv\",\n    \"id_filename\": \"data/PEMS03/PEMS03.txt\",\n    \"graph_signal_matrix_filename\": \"data/PEMS03/PEMS03.npz\",\n    \"num_of_vertices\": 358,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12,\n    \"num_of_features\": 1\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS04/individual_GLU.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"GLU\",\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"learning_rate\": 1e-3,\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS04/PEMS04.csv\",\n    \"id_filename\": null,\n    \"graph_signal_matrix_filename\": \"data/PEMS04/PEMS04.npz\",\n    \"num_of_vertices\": 307,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS04/individual_GLU_mask_emb.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"GLU\",\n    \"temporal_emb\": true,\n    \"spatial_emb\": true,\n    \"use_mask\": true,\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"optimizer\": \"adam\",\n    \"learning_rate\": 1e-3,\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS04/PEMS04.csv\",\n    \"id_filename\": null,\n    \"graph_signal_matrix_filename\": \"data/PEMS04/PEMS04.npz\",\n    \"num_of_vertices\": 307,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12,\n    \"num_of_features\": 1\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS04/individual_relu.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"relu\",\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"learning_rate\": 1e-3,\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS04/PEMS04.csv\",\n    \"id_filename\": null,\n    \"graph_signal_matrix_filename\": \"data/PEMS04/PEMS04.npz\",\n    \"num_of_vertices\": 307,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS04/sharing_GLU.json",
    "content": "{\n    \"module_type\": \"sharing\",\n    \"act_type\": \"GLU\",\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"learning_rate\": 1e-3,\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS04/PEMS04.csv\",\n    \"id_filename\": null,\n    \"graph_signal_matrix_filename\": \"data/PEMS04/PEMS04.npz\",\n    \"num_of_vertices\": 307,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS04/sharing_relu.json",
    "content": "{\n    \"module_type\": \"sharing\",\n    \"act_type\": \"relu\",\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"learning_rate\": 1e-3,\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS04/PEMS04.csv\",\n    \"id_filename\": null,\n    \"graph_signal_matrix_filename\": \"data/PEMS04/PEMS04.npz\",\n    \"num_of_vertices\": 307,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS07/individual_GLU_mask_emb.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"GLU\",\n    \"temporal_emb\": true,\n    \"spatial_emb\": true,\n    \"use_mask\": true,\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"optimizer\": \"adam\",\n    \"learning_rate\": 1e-3,\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": [0, 1],\n    \"adj_filename\": \"data/PEMS07/PEMS07.csv\",\n    \"id_filename\": null,\n    \"graph_signal_matrix_filename\": \"data/PEMS07/PEMS07.npz\",\n    \"num_of_vertices\": 883,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12,\n    \"num_of_features\": 1\n}"
  },
  {
    "path": "Experiments/STSGCN/config/PEMS08/individual_GLU_mask_emb.json",
    "content": "{\n    \"module_type\": \"individual\",\n    \"act_type\": \"GLU\",\n    \"temporal_emb\": true,\n    \"spatial_emb\": true,\n    \"use_mask\": true,\n    \"first_layer_embedding_size\": 64,\n    \"filters\": [\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64],\n        [64, 64, 64]\n    ],\n    \"batch_size\": 32,\n    \"optimizer\": \"adam\",\n    \"learning_rate\": 1e-3,\n    \"epochs\": 200,\n    \"max_update_factor\": 1,\n    \"ctx\": 0,\n    \"adj_filename\": \"data/PEMS08/PEMS08.csv\",\n    \"id_filename\": null,\n    \"graph_signal_matrix_filename\": \"data/PEMS08/PEMS08.npz\",\n    \"num_of_vertices\": 170,\n    \"points_per_hour\": 12,\n    \"num_for_predict\": 12,\n    \"num_of_features\": 1\n}"
  },
  {
    "path": "Experiments/ST_MGCN/ST_MGCN_Obj.py",
    "content": "import os\r\nimport nni\r\nimport GPUtil\r\nimport numpy as np\r\n\r\nfrom UCTB.dataset import NodeTrafficLoader\r\nfrom UCTB.model import ST_MGCN\r\nfrom UCTB.evaluation import metric\r\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\r\n\r\ndef stmeta_param_parser():\r\n    import argparse\r\n    parser = argparse.ArgumentParser(description=\"Argument Parser\")\r\n    # data source\r\n    parser.add_argument('--Dataset', default='Metro')\r\n    parser.add_argument('--City', default='Shanghai')\r\n    # network parameter\r\n    parser.add_argument('--CT', default='6', type=int)\r\n    parser.add_argument('--PT', default='7', type=int)\r\n    parser.add_argument('--TT', default='4', type=int)\r\n    parser.add_argument('--K', default='1', type=int)\r\n    parser.add_argument('--L', default='1', type=int)\r\n    parser.add_argument('--Graph', default='Distance-Correlation-Line')\r\n    parser.add_argument('--LSTMUnits', default='128', type=int)\r\n    parser.add_argument('--LSTMLayers', default='3', type=int)\r\n    # Training data parameters\r\n    parser.add_argument('--DataRange', default='All')\r\n    parser.add_argument('--TrainDays', default='365')\r\n    parser.add_argument('--test_ratio', default=0.1, type=float)\r\n    # Graph parameter\r\n    parser.add_argument('--TC', default='0', type=float)\r\n    parser.add_argument('--TD', default='1000', type=float)\r\n    parser.add_argument('--TI', default='500', type=float)\r\n    # training parameters\r\n    parser.add_argument('--Epoch', default='20000', type=int)\r\n    parser.add_argument('--Train', default='True')\r\n    parser.add_argument('--lr', default='5e-4', type=float)\r\n    parser.add_argument('--ESlength', default='50', type=int)\r\n    parser.add_argument('--patience', default='0.1', type=float)\r\n    parser.add_argument('--BatchSize', default='32', type=int)\r\n    # device parameter\r\n    parser.add_argument('--Device', default='0', type=str)\r\n    # version control\r\n    parser.add_argument('--CodeVersion', default='V')\r\n    # Merge parameter\r\n    parser.add_argument('--MergeIndex', default=6, type=int)\r\n    parser.add_argument('--MergeWay', default='sum', type=str)\r\n    return parser\r\n\r\nparser = stmeta_param_parser()\r\nargs = vars(parser.parse_args())\r\n\r\nnni_params = nni.get_next_parameter()\r\nnni_sid = nni.get_sequence_id()\r\nif nni_params:\r\n    args.update(nni_params)\r\n    args['CodeVersion'] += str(nni_sid)\r\n\r\nmodel_dir = os.path.join('model_dir', args['City'])\r\ncode_version = 'ST_MMGCN_{}_K{}L{}_{}_F{}'.format(''.join([e[0] for e in args['Graph'].split('-')]),\r\n                                              args['K'], args['L'], args['CodeVersion'],int(args['MergeIndex'])*5)\r\n\r\ndeviceIDs = GPUtil.getAvailable(order='memory', limit=2, maxLoad=1, maxMemory=0.7,\r\n                                includeNan=False, excludeID=[], excludeUUID=[])\r\n\r\nif len(deviceIDs) == 0:\r\n    current_device = '-1'\r\nelse:\r\n    if nni_params:\r\n        current_device = str(deviceIDs[int(nni_sid) % len(deviceIDs)])\r\n    else:\r\n        current_device = str(deviceIDs[0])\r\n\r\n# Config data loader\r\ndata_loader = NodeTrafficLoader(dataset=args['Dataset'], city=args['City'],\r\n                                test_ratio=float(args['test_ratio']),\r\n                                data_range=args['DataRange'], train_data_length=args['TrainDays'],\r\n                                closeness_len=int(args['CT']), period_len=int(args['PT']), trend_len=int(args['TT']),\r\n                                normalize=True, MergeIndex=args['MergeIndex'],\r\n                                MergeWay=args[\"MergeWay\"])\r\n\r\n# build graphs\r\ngraph_obj = GraphGenerator(graph=args['Graph'],\r\n                           data_loader=data_loader,\r\n                           threshold_distance=args['TD'],\r\n                           threshold_correlation=args['TC'],\r\n                           threshold_interaction=args['TI'])\r\n\r\nST_MGCN_Obj = ST_MGCN(T=int(args['CT']) + int(args['PT']) + int(args['TT']),\r\n                      input_dim=1,\r\n                      external_dim=data_loader.external_dim,\r\n                      num_graph=graph_obj.LM.shape[0],\r\n                      gcl_k=args['K'],\r\n                      gcl_l=args['L'],\r\n                      lstm_units=args['LSTMUnits'],\r\n                      lstm_layers=args['LSTMLayers'],\r\n                      lr=args['lr'],\r\n                      code_version=code_version,\r\n                      model_dir=model_dir,\r\n                      gpu_device=current_device)\r\n\r\nST_MGCN_Obj.build()\r\n\r\nprint(args['Dataset'], args['City'], code_version)\r\nprint(ST_MGCN_Obj.trainable_vars)\r\n\r\n# Training\r\nif args['Train'] == 'True':\r\n    ST_MGCN_Obj.fit(traffic_flow=np.concatenate((np.transpose(data_loader.train_closeness, [0, 2, 1, 3]),\r\n                                                 np.transpose(data_loader.train_period, [0, 2, 1, 3]),\r\n                                                 np.transpose(data_loader.train_trend, [0, 2, 1, 3])), axis=1),\r\n                    laplace_matrix=graph_obj.LM,\r\n                    target=data_loader.train_y,\r\n                    external_feature= None,\r\n                    early_stop_method='t-test',\r\n                    output_names=('loss', ),\r\n                    evaluate_loss_name='loss',\r\n                    early_stop_length=int(args['ESlength']),\r\n                    early_stop_patience=float(args['patience']),\r\n                    sequence_length=data_loader.train_sequence_len,\r\n                    save_model=True,\r\n                    batch_size=int(args['BatchSize']))\r\n\r\nST_MGCN_Obj.load(code_version)\r\n\r\n# Evaluate\r\nprediction = ST_MGCN_Obj.predict(traffic_flow=np.concatenate((np.transpose(data_loader.test_closeness, [0, 2, 1, 3]),\r\n                                                             np.transpose(data_loader.test_period, [0, 2, 1, 3]),\r\n                                                             np.transpose(data_loader.test_trend, [0, 2, 1, 3])), axis=1),\r\n                                 laplace_matrix=graph_obj.LM,\r\n                                 external_feature=None,\r\n                                 sequence_length=data_loader.test_sequence_len,\r\n                                 output_names=['prediction'],\r\n                                 cache_volume=int(args['BatchSize']))\r\n\r\ntest_rmse = metric.rmse(prediction=data_loader.normalizer.inverse_transform(prediction['prediction']),\r\n                        target=data_loader.normalizer.inverse_transform(data_loader.test_y),\r\n                        threshold=0)\r\n\r\nprint('Test result', test_rmse)\r\n\r\nval_loss = ST_MGCN_Obj.load_event_scalar('val_loss')\r\n\r\nbest_val_loss = min([e[-1] for e in val_loss])\r\n\r\nbest_val_loss = data_loader.normalizer.inverse_transform(best_val_loss)\r\n\r\nprint('Best val result', best_val_loss)\r\n\r\ntime_consumption = [val_loss[e][0] - val_loss[e-1][0] for e in range(1, len(val_loss))]\r\ntime_consumption = sum([e for e in time_consumption if e < (min(time_consumption) * 10)]) / 3600\r\nprint('Converged using %.2f hour / %s epochs' % (time_consumption, ST_MGCN_Obj._global_step))\r\n\r\nif nni_params:\r\n    nni.report_final_result({\r\n        'default': best_val_loss,\r\n        'test-rmse': test_rmse,\r\n    })\r\n"
  },
  {
    "path": "Experiments/ST_MGCN/bike_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python ST_MGCN_Obj.py '\n                         '--Dataset Bike '\n                         '--CT 6 '\n                         '--PT 7 '\n                         '--TT 4 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 3 '\n                         '--DataRange All '\n                         '--TrainDays 365 '\n                         '--TC 0 '\n                         '--TD 1000 '\n                         '--TI 500 '\n                         '--Epoch 10000 '\n                         '--Train True '\n                         '--lr 5e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay sum '\n                         '--Device 1 '\n                         '')\n\n\"\"\"\nV1\nLSTMLayers : 3 => 4\nK : 1 => 3\n\"\"\"\nif __name__ == \"__main__\":\n\n    \"\"\"\n    Multiple Graphs\n    \"\"\"\n    # NYC\n    os.system(shared_params_st_mgcn + ' --City NYC --K 1 --L 1 --DataRange 0.125 --TrainDays 60'\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 1')\n    os.system(shared_params_st_mgcn + ' --City NYC --K 1 --L 1 --DataRange 0.25 --TrainDays 91'\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 3')\n    os.system(shared_params_st_mgcn + ' --City NYC --K 1 --L 1 --DataRange 0.5 --TrainDays 183'\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 6')\n    os.system(shared_params_st_mgcn + ' --City NYC --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 12')\n    \n    # Chicago \n    os.system(shared_params_st_mgcn + ' --City Chicago --K 1 --L 1 --DataRange 0.125 --TrainDays 60'\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 1')\n    os.system(shared_params_st_mgcn + ' --City Chicago --K 1 --L 1 --DataRange 0.25 --TrainDays 91'\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 3')\n    os.system(shared_params_st_mgcn + ' --City Chicago --K 1 --L 1 --DataRange 0.5 --TrainDays 183'\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 6')\n    os.system(shared_params_st_mgcn + ' --City Chicago --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 12')\n    \n    # DC\n    os.system(shared_params_st_mgcn + ' --City DC --K 1 --L 1 --DataRange 0.125 --TrainDays 60'\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 1')\n    os.system(shared_params_st_mgcn + ' --City DC --K 1 --L 1 --DataRange 0.25 --TrainDays 91'\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 3')\n    os.system(shared_params_st_mgcn + ' --City DC --K 1 --L 1 --DataRange 0.5 --TrainDays 183'\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 6')\n    os.system(shared_params_st_mgcn + ' --City DC --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 12')\n"
  },
  {
    "path": "Experiments/ST_MGCN/cs_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python ST_MGCN_Obj.py '\n                         '--Dataset ChargeStation '\n                         '--CT 6 '\n                         '--PT 7 '\n                         '--TT 4 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 3 '\n                         '--DataRange All '\n                         '--TrainDays All '\n                         '--TC 0.1 '\n                         '--TD 1000 '\n                         '--TI 500 '\n                         '--Epoch 10000 '\n                         '--Train True '\n                         '--lr 5e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay max '\n                         '--Device 1 ')\n\nif __name__ == \"__main__\":\n    \n    os.system(shared_params_st_mgcn + ' --City Beijing --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation --MergeIndex 1')\n\n    os.system(shared_params_st_mgcn + ' --City Beijing --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation --MergeIndex 2')"
  },
  {
    "path": "Experiments/ST_MGCN/didi_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python ST_MGCN_Obj.py '\n                         '--Dataset DiDi '\n                         '--CT 6 '\n                         '--PT 7 '\n                         '--TT 4 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 3 '\n                         '--DataRange All '\n                         '--TrainDays All '\n                         '--TC 0.65 '\n                         '--TD 7500 '\n                         '--TI 30 '\n                         '--Epoch 10000 '\n                         '--Train True '\n                         '--lr 1e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay sum '\n                         '--Device 1 ')\n\nif __name__ == \"__main__\":\n\n    \"\"\"\n    Multiple Graphs\n    \"\"\"\n    # Chengdu\n    os.system(shared_params_st_mgcn + ' --City Chengdu --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 1')\n    os.system(shared_params_st_mgcn + ' --City Chengdu --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 3')\n    os.system(shared_params_st_mgcn + ' --City Chengdu --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 6')\n    os.system(shared_params_st_mgcn + ' --City Chengdu --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 12')\n\n    # Xian\n    os.system(shared_params_st_mgcn + ' --City Xian --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 1')\n    os.system(shared_params_st_mgcn + ' --City Xian --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 3')\n    os.system(shared_params_st_mgcn + ' --City Xian --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 6')\n    os.system(shared_params_st_mgcn + ' --City Xian --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 12')\n"
  },
  {
    "path": "Experiments/ST_MGCN/metr_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python ST_MGCN_Obj.py '\n                         '--Dataset METR '\n                         '--CT 6 '\n                         '--PT 7 '\n                         '--TT 4 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 3 '\n                         '--DataRange All '\n                         '--TrainDays All '\n                         '--TC 0.63 '\n                         '--TD 5500 '\n                         '--TI 30 '\n                         '--Epoch 10000 '\n                         '--test_ratio 0.2 '\n                         '--Train True '\n                         '--lr 1e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay average '\n                         '--Device 1 ')\n\nif __name__ == \"__main__\":\n\n    \"\"\"\n    Multiple Graphs\n    \"\"\"\n    os.system(shared_params_st_mgcn + ' --City LA --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation --MergeIndex 1')\n\n    os.system(shared_params_st_mgcn + ' --City LA --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation --MergeIndex 3')\n\n    os.system(shared_params_st_mgcn + ' --City LA --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation --MergeIndex 6')\n\n    os.system(shared_params_st_mgcn + ' --City LA --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation --MergeIndex 12')\n"
  },
  {
    "path": "Experiments/ST_MGCN/metro_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python ST_MGCN_Obj.py '\n                         '--Dataset Metro '\n                         '--CT 6 '\n                         '--PT 7 '\n                         '--TT 4 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 3 '\n                         '--DataRange All '\n                         '--TrainDays All '\n                         '--TC 0.7 '\n                         '--TD 5000 '\n                         '--TI 30 '\n                         '--Epoch 10000 '\n                         '--Train True '\n                         '--lr 1e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay sum '\n                         '--Device 1 ')\n\nif __name__ == \"__main__\":\n\n    \"\"\"\n    Multiple Graphs\n    \"\"\"\n    # Shanghai\n    os.system(shared_params_st_mgcn + ' --City Shanghai --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation-Line --MergeIndex 1')\n    os.system(shared_params_st_mgcn + ' --City Shanghai --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation-Line --MergeIndex 3')\n    os.system(shared_params_st_mgcn + ' --City Shanghai --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation-Line --MergeIndex 6')\n    os.system(shared_params_st_mgcn + ' --City Shanghai --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation-Line --MergeIndex 12')\n\n    # Chongqing\n    os.system(shared_params_st_mgcn + ' --City Chongqing --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation-Line --MergeIndex 1')\n    os.system(shared_params_st_mgcn + ' --City Chongqing --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation-Line --MergeIndex 3')\n    os.system(shared_params_st_mgcn + ' --City Chongqing --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation-Line --MergeIndex 6')                                \n    os.system(shared_params_st_mgcn + ' --City Chongqing --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation-Line --MergeIndex 12')\n                "
  },
  {
    "path": "Experiments/ST_MGCN/param_search.yml",
    "content": "authorName: DiChai\nexperimentName: network_search\ntrialConcurrency: 2\nmaxExecDuration: 24h\nmaxTrialNum: 50\ntrainingServicePlatform: local\n# The path to Search Space\n#searchSpacePath: lstm_search.json\nsearchSpacePath: params_search.json\nuseAnnotation: false\ntuner:\n  builtinTunerName: TPE\n# The path and the running command of trial\ntrial:\n  command: python ST_MGCN_Obj.py\n  codeDir: .\n  gpuNum: 1"
  },
  {
    "path": "Experiments/ST_MGCN/params_search.json",
    "content": "{\n    \"K\": {\"_type\":\"choice\",\"_value\":[3]},\n\n    \"L\": {\"_type\":\"choice\",\"_value\":[1]},\n\n    \"lr\": {\"_type\":\"choice\",\"_value\":[0.00005]},\n\n    \"LSTMLayers\": {\"_type\":\"choice\",\"_value\":[3, 4]},\n\n    \"LSTMUnits\": {\"_type\":\"choice\",\"_value\":[64, 128]}\n}"
  },
  {
    "path": "Experiments/ST_MGCN/pems_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python ST_MGCN_Obj.py '\n                         '--Dataset PEMS '\n                         '--CT 6 '\n                         '--PT 7 '\n                         '--TT 4 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 3 '\n                         '--DataRange All '\n                         '--TrainDays All '\n                         '--TC 0.73 '\n                         '--TD 5500 '\n                         '--TI 30 '\n                         '--Epoch 10000 '\n                         '--test_ratio 0.2 '\n                         '--Train True '\n                         '--lr 1e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay average '\n                         '--Device 1 ')\n\nif __name__ == \"__main__\":\n\n    \"\"\"\n    Multiple Graphs\n    \"\"\"\n    os.system(shared_params_st_mgcn + ' --City BAY --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation --MergeIndex 1')\n\n    os.system(shared_params_st_mgcn + ' --City BAY --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation --MergeIndex 3')\n\n    os.system(shared_params_st_mgcn + ' --City BAY --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation --MergeIndex 6')\n\n    os.system(shared_params_st_mgcn + ' --City BAY --K 1 --L 1  '\n                                      ' --Graph Distance-Correlation --MergeIndex 12')\n"
  },
  {
    "path": "Experiments/ST_MGCN/street_didi_trial.py",
    "content": "import os\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nshared_params_st_mgcn = ('python ST_MGCN_Obj.py '\n                         '--Dataset DiDi '\n                         '--CT 6 '\n                         '--PT 7 '\n                         '--TT 4 '\n                         '--LSTMUnits 64 '\n                         '--LSTMLayers 3 '\n                         '--DataRange All '\n                         '--TrainDays All '\n                         '--TC 0.65 '\n                         '--TD 7500 '\n                         '--TI 30 '\n                         '--Epoch 10000 '\n                         '--Train True '\n                         '--lr 1e-4 '\n                         '--patience 0.1 '\n                         '--ESlength 100 '\n                         '--BatchSize 16 '\n                         '--MergeWay sum '\n                         '--Device 1 ')\n\nif __name__ == \"__main__\":\n\n    \"\"\"\n    Multiple Graphs\n    \"\"\"\n    # Chengdu\n    os.system(shared_params_st_mgcn + ' --City Chengdu_Street --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 3')\n    os.system(shared_params_st_mgcn + ' --City Chengdu_Street --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 6')\n    os.system(shared_params_st_mgcn + ' --City Chengdu_Street --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 12')\n\n    # Xian\n    os.system(shared_params_st_mgcn + ' --City Xian_Street --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 3')\n    os.system(shared_params_st_mgcn + ' --City Xian_Street --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 6')\n    os.system(shared_params_st_mgcn + ' --City Xian_Street --K 1 --L 1 '\n                                      ' --Graph Distance-Correlation-Interaction --MergeIndex 12')\n"
  },
  {
    "path": "Experiments/ST_ResNet/ST_ResNet.py",
    "content": "import nni\nimport GPUtil\n\nfrom UCTB.dataset import GridTrafficLoader\nfrom UCTB.model import ST_ResNet\nfrom UCTB.evaluation import metric\n\nargs = {\n    'dataset': 'DiDi',\n    'city': 'Xian',\n    'num_residual_unit': 4,\n    'conv_filters': 64,\n    'kernel_size': 3,\n    'lr': 1e-5,\n    'batch_size': 32,\n    'MergeIndex': 6\n}\n\ncode_version = 'ST_ResNet_{}_{}_F{}'.format(args['dataset'], args['city'], int(args['MergeIndex'])*5)\n\nnni_params = nni.get_next_parameter()\nnni_sid = nni.get_sequence_id()\nif nni_params:\n    args.update(nni_params)\n    code_version += ('_' + str(nni_sid))\n\ndeviceIDs = GPUtil.getAvailable(order='memory', limit=2, maxLoad=1, maxMemory=0.7,\n                                includeNan=False, excludeID=[], excludeUUID=[])\n\nif len(deviceIDs) == 0:\n    current_device = '-1'\nelse:\n    if nni_params:\n        current_device = str(deviceIDs[int(nni_sid) % len(deviceIDs)])\n    else:\n        current_device = str(deviceIDs[0])\n\n# Config data loader\ndata_loader = GridTrafficLoader(dataset=args['dataset'], city=args['city'], closeness_len=6, period_len=7, trend_len=4, MergeIndex=args['MergeIndex'])\n\nST_ResNet_Obj = ST_ResNet(closeness_len=data_loader.closeness_len,\n                          period_len=data_loader.period_len,\n                          trend_len=data_loader.trend_len,\n                          external_dim=data_loader.external_dim, lr=args['lr'],\n                          num_residual_unit=args['num_residual_unit'], conv_filters=args['conv_filters'],\n                          kernel_size=args['kernel_size'], width=data_loader.width, height=data_loader.height,\n                          gpu_device=current_device, code_version=code_version)\n\nST_ResNet_Obj.build()\n\nprint(args['dataset'], args['city'], code_version)\nprint('Number of trainable variables', ST_ResNet_Obj.trainable_vars)\nprint('Number of training samples', data_loader.train_sequence_len)\n\nprint('debug')\n\n# Training\nST_ResNet_Obj.fit(closeness_feature=data_loader.train_closeness,\n                  period_feature=data_loader.train_period,\n                  trend_feature=data_loader.train_trend,\n                  target=data_loader.train_y,\n                  external_feature=data_loader.train_ef,\n                  sequence_length=data_loader.train_sequence_len,\n                  batch_size=args['batch_size'], early_stop_length=200,\n                  validate_ratio=0.1)\n\n# Predict\nprediction = ST_ResNet_Obj.predict(closeness_feature=data_loader.test_closeness,\n                                   period_feature=data_loader.test_period,\n                                   trend_feature=data_loader.test_trend,\n                                   target=data_loader.test_y,\n                                   external_feature=data_loader.test_ef,\n                                   sequence_length=data_loader.test_sequence_len)\n\n# Compute metric\ntest_rmse = metric.rmse(prediction=data_loader.normalizer.inverse_transform(prediction['prediction']),\n                        target=data_loader.normalizer.inverse_transform(data_loader.test_y))\n\n# Evaluate\nval_loss = ST_ResNet_Obj.load_event_scalar('val_loss')\n\nbest_val_loss = min([e[-1] for e in val_loss])\nbest_val_loss = data_loader.normalizer.inverse_transform(best_val_loss)\n\nprint('Best val result', best_val_loss)\nprint('Test result', test_rmse)\n\nprint('Converged using %.2f hour' % ((val_loss[-1][0] - val_loss[0][0]) / 3600))\nif nni_params:\n    nni.report_final_result({\n        'default': best_val_loss,\n        'test-rmse': test_rmse\n    })"
  },
  {
    "path": "Experiments/ST_ResNet/param_search.yml",
    "content": "authorName: DiChai\r\nexperimentName: search_space\r\ntrialConcurrency: 1\r\nmaxExecDuration: 24h\r\nmaxTrialNum: 200\r\ntrainingServicePlatform: local\r\n# The path to Search Space\r\nsearchSpacePath: search_space.json\r\nuseAnnotation: false\r\ntuner:\r\n  builtinTunerName: GridSearch\r\n# The path and the running command of trial\r\ntrial:\r\n  command: python ST_ResNet.py\r\n  codeDir: .\r\n  gpuNum: 1"
  },
  {
    "path": "Experiments/ST_ResNet/search_space.json",
    "content": "{\r\n    \"num_residual_unit\": {\"_type\":\"choice\",\"_value\":[2, 3, 4, 5, 6]},\r\n\r\n    \"conv_filters\": {\"_type\":\"choice\",\"_value\":[32, 64, 128]},\r\n\r\n    \"kernel_size\": {\"_type\":\"choice\",\"_value\":[3, 4, 5]},\r\n\r\n    \"lr\": {\"_type\":\"choice\",\"_value\":[0.0001, 0.00002, 0.00004, 0.00008, 0.00001]},\r\n\r\n    \"batch_size\": {\"_type\":\"choice\",\"_value\":[32, 64, 128, 256]}\r\n}"
  },
  {
    "path": "Experiments/StabilityTest/CPT_AMulti_GCLSTM_Obj.py",
    "content": "import os\r\nimport numpy as np\r\n\r\nfrom UCTB.dataset import NodeTrafficLoader_CPT\r\nfrom UCTB.model import STMeta_V1\r\nfrom UCTB.evaluation import metric\r\nfrom UCTB.model_unit import GraphBuilder\r\nfrom UCTB.preprocess import is_work_day_china\r\n\r\nmodel_dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'model_dir')\r\n\r\n\r\ndef cpt_stmeta_param_parser():\r\n    import argparse\r\n    parser = argparse.ArgumentParser(description=\"Argument Parser\")\r\n    # data source\r\n    parser.add_argument('--Dataset', default='DiDi')\r\n    parser.add_argument('--City', default='Xian')\r\n    # network parameter\r\n    parser.add_argument('--CT', default='6', type=int)\r\n    parser.add_argument('--PT', default='7', type=int)\r\n    parser.add_argument('--TT', default='4', type=int)\r\n    parser.add_argument('--K', default='1', type=int)\r\n    parser.add_argument('--L', default='1', type=int)\r\n    parser.add_argument('--Graph', default='Distance-Interaction-Correlation')\r\n    parser.add_argument('--GLL', default='1', type=int)\r\n    parser.add_argument('--LSTMUnits', default='64', type=int)\r\n    parser.add_argument('--GALUnits', default='64', type=int)\r\n    parser.add_argument('--GALHeads', default='2', type=int)\r\n    parser.add_argument('--DenseUnits', default='32', type=int)\r\n    parser.add_argument('--Normalize', default='True', type=str)\r\n    # Training data parameters\r\n    parser.add_argument('--DataRange', default='All')\r\n    parser.add_argument('--TrainDays', default='All')\r\n    # Graph parameter\r\n    parser.add_argument('--TC', default='0.7', type=float)\r\n    parser.add_argument('--TD', default='3000', type=float)\r\n    parser.add_argument('--TI', default='100', type=float)\r\n    # training parameters\r\n    parser.add_argument('--Epoch', default='5000', type=int)\r\n    parser.add_argument('--Train', default='True', type=str)\r\n    parser.add_argument('--lr', default='1e-4', type=float)\r\n    parser.add_argument('--ESlength', default='200', type=int)\r\n    parser.add_argument('--patience', default='0.1', type=float)\r\n    parser.add_argument('--BatchSize', default='128', type=int)\r\n    # device parameter\r\n    parser.add_argument('--Device', default='0,1', type=str)\r\n    # version control\r\n    parser.add_argument('--Group', default='Xian')\r\n    parser.add_argument('--CodeVersion', default='ParamTuner')\r\n    return parser\r\n\r\n\r\nclass SubwayTrafficLoader(NodeTrafficLoader_CPT):\r\n\r\n    def __init__(self,\r\n                 dataset,\r\n                 city,\r\n                 C_T,\r\n                 P_T,\r\n                 T_T,\r\n                 data_range='All',\r\n                 train_data_length='All',\r\n                 test_ratio=0.1,\r\n                 graph='Correlation',\r\n                 TD=1000,\r\n                 TC=0,\r\n                 TI=500,\r\n                 workday_parser=is_work_day_china,\r\n                 normalize=False,\r\n                 with_lm=True):\r\n\r\n        super(SubwayTrafficLoader, self).__init__(dataset=dataset,\r\n                                                  city=city,\r\n                                                  data_range=data_range,\r\n                                                  train_data_length=train_data_length,\r\n                                                  test_ratio=test_ratio,\r\n                                                  graph=graph, TD=TD, TC=TC, TI=TI,\r\n                                                  C_T=C_T, P_T=P_T, T_T=T_T,\r\n                                                  workday_parser=workday_parser,\r\n                                                  normalize=normalize,\r\n                                                  with_lm=with_lm)\r\n        if with_lm:\r\n            LM = []\r\n            for graph_name in graph.split('-'):\r\n                if graph_name.lower() == 'neighbor':\r\n                    LM.append(\r\n                        GraphBuilder.adjacent_to_laplacian(self.dataset.data.get('contribute_data').get('graph_neighbors')))\r\n                if graph_name.lower() == 'line':\r\n                    LM.append(GraphBuilder.adjacent_to_laplacian(self.dataset.data.get('contribute_data').get('graph_lines')))\r\n                if graph_name.lower() == 'transfer':\r\n                    LM.append(\r\n                        GraphBuilder.adjacent_to_laplacian(self.dataset.data.get('contribute_data').get('graph_transfer')))\r\n            if len(LM) > 0:\r\n                if len(self.LM) == 0:\r\n                    self.LM = np.array(LM, dtype=np.float32)\r\n                else:\r\n                    self.LM = np.concatenate((self.LM, LM), axis=0)\r\n\r\n\r\nparser = cpt_stmeta_param_parser()\r\nargs = vars(parser.parse_args())\r\n\r\nmodel_dir = os.path.join(model_dir_path, args['Group'])\r\ncode_version = 'CPT_STMeta_{}_K{}L{}_{}'.format(''.join([e[0] for e in args['Graph'].split('-')]),\r\n                                                      args['K'], args['L'], args['CodeVersion'])\r\n\r\n# Config data loader\r\ndata_loader = SubwayTrafficLoader(dataset=args['Dataset'], city=args['City'],\r\n                                  data_range=args['DataRange'], train_data_length=args['TrainDays'],\r\n                                  test_ratio=0.1,\r\n                                  C_T=int(args['CT']), P_T=int(args['PT']), T_T=int(args['TT']),\r\n                                  TI=args['TI'], TD=args['TD'], TC=args['TC'],\r\n                                  normalize=True if args['Normalize'] == 'True' else False,\r\n                                  graph=args['Graph'], with_lm=True)\r\n\r\nde_normalizer = None if args['Normalize'] == 'False' else data_loader.normalizer.min_max_denormal\r\n\r\nCPT_STMeta_Obj = STMeta_V1(num_node=data_loader.station_number,\r\n                                  num_graph=data_loader.LM.shape[0],\r\n                                  external_dim=data_loader.external_dim,\r\n                                  C_T=int(args['CT']), P_T=int(args['PT']), T_T=int(args['TT']),\r\n                                  GCN_K=int(args['K']),\r\n                                  GCN_layers=int(args['L']),\r\n                                  GCLSTM_layers=int(args['GLL']),\r\n                                  gal_units=int(args['GALUnits']),\r\n                                  gal_num_heads=int(args['GALHeads']),\r\n                                  num_hidden_units=int(args['LSTMUnits']),\r\n                                  num_filter_conv1x1=int(args['DenseUnits']),\r\n                                  lr=float(args['lr']),\r\n                                  code_version=code_version,\r\n                                  model_dir=model_dir,\r\n                                  GPU_DEVICE=args['Device'])\r\n\r\nimport json\r\n\r\nwith open(os.path.join(CPT_STMeta_Obj._log_dir, 'params.json'), 'w') as f:\r\n    json.dump(args, f)\r\n\r\nCPT_STMeta_Obj.build()\r\n\r\nprint(args['Dataset'], args['City'], code_version)\r\nprint('Number of trainable variables', CPT_STMeta_Obj.trainable_vars)\r\n\r\n# Training\r\nif args['Train'] == 'True':\r\n    CPT_STMeta_Obj.fit(closeness_feature=data_loader.train_closeness,\r\n                       period_feature=data_loader.train_period,\r\n                       trend_feature=data_loader.train_trend,\r\n                       laplace_matrix=data_loader.LM,\r\n                       target=data_loader.train_y,\r\n                       external_feature=data_loader.train_ef,\r\n                       early_stop_method='t-test',\r\n                       early_stop_length=int(args['ESlength']),\r\n                       early_stop_patience=float(args['patience']),\r\n                       batch_size=int(args['BatchSize']),\r\n                       max_epoch=int(args['Epoch']))\r\n\r\nCPT_STMeta_Obj.load(code_version)\r\n\r\n# Evaluate\r\ntest_error = CPT_STMeta_Obj.evaluate(closeness_feature=data_loader.test_closeness,\r\n                                     period_feature=data_loader.test_period,\r\n                                     trend_feature=data_loader.test_trend,\r\n                                     laplace_matrix=data_loader.LM,\r\n                                     target=data_loader.test_y,\r\n                                     external_feature=data_loader.test_ef,\r\n                                     cache_volume=int(args['BatchSize']),\r\n                                     metrics=[metric.rmse, metric.mape],\r\n                                     de_normalizer=de_normalizer,\r\n                                     threshold=0)\r\n\r\nprint('Test result', test_error)"
  },
  {
    "path": "Experiments/StabilityTest/CPT_AMulti_GCLSTM_Simplify_Obj.py",
    "content": "import os\r\nimport numpy as np\r\n\r\nfrom UCTB.dataset import NodeTrafficLoader_CPT\r\nfrom UCTB.model import STMeta_V2\r\nfrom UCTB.evaluation import metric\r\nfrom UCTB.model_unit import GraphBuilder\r\nfrom UCTB.preprocess import is_work_day_china\r\n\r\nmodel_dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'model_dir')\r\n\r\n\r\ndef cpt_stmeta_param_parser():\r\n    import argparse\r\n    parser = argparse.ArgumentParser(description=\"Argument Parser\")\r\n    # data source\r\n    parser.add_argument('--Dataset', default='DiDi')\r\n    parser.add_argument('--City', default='Xian')\r\n    # network parameter\r\n    parser.add_argument('--CT', default='6', type=int)\r\n    parser.add_argument('--PT', default='7', type=int)\r\n    parser.add_argument('--TT', default='4', type=int)\r\n    parser.add_argument('--K', default='1', type=int)\r\n    parser.add_argument('--L', default='1', type=int)\r\n    parser.add_argument('--Graph', default='Distance-Interaction-Correlation')\r\n    parser.add_argument('--GLL', default='1', type=int)\r\n    parser.add_argument('--LSTMUnits', default='64', type=int)\r\n    parser.add_argument('--GALUnits', default='64', type=int)\r\n    parser.add_argument('--GALHeads', default='2', type=int)\r\n    parser.add_argument('--DenseUnits', default='32', type=int)\r\n    parser.add_argument('--Normalize', default='True', type=str)\r\n    # Training data parameters\r\n    parser.add_argument('--DataRange', default='All')\r\n    parser.add_argument('--TrainDays', default='All')\r\n    # Graph parameter\r\n    parser.add_argument('--TC', default='0.7', type=float)\r\n    parser.add_argument('--TD', default='3000', type=float)\r\n    parser.add_argument('--TI', default='100', type=float)\r\n    # training parameters\r\n    parser.add_argument('--Epoch', default='5000', type=int)\r\n    parser.add_argument('--Train', default='True', type=str)\r\n    parser.add_argument('--lr', default='1e-4', type=float)\r\n    parser.add_argument('--ESlength', default='200', type=int)\r\n    parser.add_argument('--patience', default='0.1', type=float)\r\n    parser.add_argument('--BatchSize', default='128', type=int)\r\n    # device parameter\r\n    parser.add_argument('--Device', default='2', type=str)\r\n    # version control\r\n    parser.add_argument('--Group', default='Debug')\r\n    parser.add_argument('--CodeVersion', default='ParamTuner')\r\n    return parser\r\n\r\n\r\nclass SubwayTrafficLoader(NodeTrafficLoader_CPT):\r\n\r\n    def __init__(self,\r\n                 dataset,\r\n                 city,\r\n                 C_T,\r\n                 P_T,\r\n                 T_T,\r\n                 data_range='All',\r\n                 train_data_length='All',\r\n                 test_ratio=0.1,\r\n                 graph='Correlation',\r\n                 TD=1000,\r\n                 TC=0,\r\n                 TI=500,\r\n                 workday_parser=is_work_day_china,\r\n                 normalize=False,\r\n                 with_lm=True):\r\n\r\n        super(SubwayTrafficLoader, self).__init__(dataset=dataset,\r\n                                                  city=city,\r\n                                                  data_range=data_range,\r\n                                                  train_data_length=train_data_length,\r\n                                                  test_ratio=test_ratio,\r\n                                                  graph=graph, TD=TD, TC=TC, TI=TI,\r\n                                                  C_T=C_T, P_T=P_T, T_T=T_T,\r\n                                                  workday_parser=workday_parser,\r\n                                                  normalize=normalize,\r\n                                                  with_lm=with_lm)\r\n        if with_lm:\r\n            LM = []\r\n            for graph_name in graph.split('-'):\r\n                if graph_name.lower() == 'neighbor':\r\n                    LM.append(\r\n                        GraphBuilder.adjacent_to_laplacian(self.dataset.data.get('contribute_data').get('graph_neighbors')))\r\n                if graph_name.lower() == 'line':\r\n                    LM.append(GraphBuilder.adjacent_to_laplacian(self.dataset.data.get('contribute_data').get('graph_lines')))\r\n                if graph_name.lower() == 'transfer':\r\n                    LM.append(\r\n                        GraphBuilder.adjacent_to_laplacian(self.dataset.data.get('contribute_data').get('graph_transfer')))\r\n            if len(LM) > 0:\r\n                if len(self.LM) == 0:\r\n                    self.LM = np.array(LM, dtype=np.float32)\r\n                else:\r\n                    self.LM = np.concatenate((self.LM, LM), axis=0)\r\n\r\n\r\nparser = cpt_stmeta_param_parser()\r\nargs = vars(parser.parse_args())\r\n\r\n\r\nmodel_dir = os.path.join(model_dir_path, args['Group'])\r\ncode_version = 'CPT_STMeta_{}_K{}L{}_{}'.format(''.join([e[0] for e in args['Graph'].split('-')]),\r\n                                                      args['K'], args['L'], args['CodeVersion'])\r\n\r\n# Config data loader\r\ndata_loader = SubwayTrafficLoader(dataset=args['Dataset'], city=args['City'],\r\n                                  data_range=args['DataRange'], train_data_length=args['TrainDays'],\r\n                                  test_ratio=0.1,\r\n                                  C_T=int(args['CT']), P_T=int(args['PT']), T_T=int(args['TT']),\r\n                                  TI=args['TI'], TD=args['TD'], TC=args['TC'],\r\n                                  normalize=True if args['Normalize'] == 'True' else False,\r\n                                  graph=args['Graph'], with_lm=True)\r\n\r\nde_normalizer = None if args['Normalize'] == 'False' else data_loader.normalizer.min_max_denormal\r\n\r\nCPT_STMeta_Obj = STMeta_V2(num_node=data_loader.station_number,\r\n                           num_graph=data_loader.LM.shape[0],\r\n                           external_dim=data_loader.external_dim,\r\n                           closeness_len=int(args['CT']), period_len=int(args['PT']), trend_len=int(args['TT']),\r\n                           gcn_k=int(args['K']),\r\n                           gcn_layers=int(args['L']),\r\n                           gclstm_layers=int(args['GLL']),\r\n                           gal_units=int(args['GALUnits']),\r\n                           gal_num_heads=int(args['GALHeads']),\r\n                           num_hidden_units=int(args['LSTMUnits']),\r\n                           num_filter_conv1x1=int(args['DenseUnits']),\r\n                           lr=float(args['lr']),\r\n                           code_version=code_version,\r\n                           model_dir=model_dir,\r\n                           gpu_device=args['Device'])\r\n\r\nCPT_STMeta_Obj.build()\r\n\r\nprint(args['Dataset'], args['City'], code_version)\r\nprint('Number of trainable variables', CPT_STMeta_Obj.trainable_vars)\r\n\r\n# Training\r\nif args['Train'] == 'True':\r\n    CPT_STMeta_Obj.fit(closeness_feature=data_loader.train_closeness,\r\n                       period_feature=data_loader.train_period,\r\n                       trend_feature=data_loader.train_trend,\r\n                       laplace_matrix=data_loader.LM,\r\n                       target=data_loader.train_y,\r\n                       external_feature=data_loader.train_ef,\r\n                       early_stop_method='t-test',\r\n                       early_stop_length=int(args['ESlength']),\r\n                       early_stop_patience=float(args['patience']),\r\n                       batch_size=int(args['BatchSize']),\r\n                       max_epoch=int(args['Epoch']))\r\n\r\nCPT_STMeta_Obj.load(code_version)\r\n\r\n# Evaluate\r\ntest_error = CPT_STMeta_Obj.evaluate(closeness_feature=data_loader.test_closeness,\r\n                                     period_feature=data_loader.test_period,\r\n                                     trend_feature=data_loader.test_trend,\r\n                                     laplace_matrix=data_loader.LM,\r\n                                     target=data_loader.test_y,\r\n                                     external_feature=data_loader.test_ef,\r\n                                     cache_volume=int(args['BatchSize']),\r\n                                     metrics=[metric.rmse, metric.mape],\r\n                                     de_normalizer=de_normalizer,\r\n                                     threshold=0)\r\n\r\nval_loss_record = CPT_STMeta_Obj.load_event_scalar(scalar_name='val_loss')\r\n\r\nimport json\r\n\r\nwith open(os.path.join(model_dir, code_version + '.json'), 'w') as f:\r\n    json.dump(args, f)\r\n\r\nprint('Test result', test_error)"
  },
  {
    "path": "Experiments/StabilityTest/Master_CS_0.py",
    "content": "import os\r\n\r\nimport warnings\r\nwarnings.filterwarnings(\"ignore\")\r\n\r\nshared_params = ('python CPT_STMeta_Simplify_Obj.py '\r\n                 '--Dataset ChargeStation '\r\n                 '--CT 6 '\r\n                 '--PT 7 '\r\n                 '--TT 4 '\r\n                 '--GLL 1 '\r\n                 '--LSTMUnits 64 '\r\n                 '--GALUnits 64 '\r\n                 '--GALHeads 2 '\r\n                 '--DenseUnits 32 '\r\n                 '--DataRange All '\r\n                 '--TrainDays All '\r\n                 '--TC 0.1 '\r\n                 '--TD 1000 '\r\n                 '--TI 500 '\r\n                 '--Epoch 10000 '\r\n                 '--Train False '\r\n                 '--lr 2e-5 '\r\n                 '--Normalize True '\r\n                 '--patience 0.1 '\r\n                 '--ESlength 200 '\r\n                 '--BatchSize 128 '\r\n                 '--Device 0 ')\r\n\r\nif __name__ == \"__main__\":\r\n\r\n    # 可以先选择在 DiDi-Xian, DiDi-Chengdu, Metro-Shanghai, ChargeStation-Beijing 这几个数据集上进行测试，因为耗时比较短\r\n\r\n    # stability test\r\n    test_times = 10\r\n    for i in range(test_times):\r\n        os.system(shared_params + '--CT 6 --PT 7 --TT 4 --City Beijing --Group Beijing'\r\n                                  ' --K 1 --L 1 --Graph Distance-Correlation --CodeVersion ST_Sim1_%s' % i)"
  },
  {
    "path": "Experiments/StabilityTest/Master_DiDi_0.py",
    "content": "# _*_ coding:utf-8 _*_\r\nimport os\r\n\r\nimport warnings\r\nwarnings.filterwarnings(\"ignore\")\r\n\r\nshared_params = ('python STMeta_V0_Obj.py '\r\n                 '--Dataset DiDi '\r\n                 '--GLL 1 '\r\n                 '--LSTMUnits 64 '\r\n                 '--GALUnits 64 '\r\n                 '--GALHeads 2 '\r\n                 '--DenseUnits 32 '\r\n                 '--DataRange All '\r\n                 '--TrainDays All '\r\n                 '--TC 0.65 '\r\n                 '--TD 7500 '\r\n                 '--TI 30 '\r\n                 '--Epoch 10000 '\r\n                 '--Train False '\r\n                 '--lr 5e-5 '\r\n                 '--Normalize True '\r\n                 '--patience 0.1 '\r\n                 '--ESlength 500 '\r\n                 '--BatchSize 128 '\r\n                 '--Device 1 ')\r\n\r\nif __name__ == \"__main__\":\r\n\r\n    # 可以先选择在 DiDi-Xian, DiDi-Chengdu, Metro-Shanghai, ChargeStation-Beijing 这几个数据集上进行测试，因为耗时比较短\r\n\r\n    # stability test\r\n    test_times = 10\r\n    for i in range(test_times):\r\n        os.system(shared_params + '--CT 6 --PT 7 --TT 4 --City Xian --Group Xian'\r\n                                  ' --K 1 --L 1 --Graph Distance-Interaction-Correlation --CodeVersion ST%s' % i)"
  },
  {
    "path": "Experiments/StabilityTest/Master_Metro_0.py",
    "content": "# _*_ coding:utf-8 _*_\r\nimport os\r\n\r\nimport warnings\r\nwarnings.filterwarnings(\"ignore\")\r\n\r\nshared_params = ('python CPT_STMeta_Simplify_Obj.py '\r\n                 '--Dataset Metro '\r\n                 '--GLL 1 '\r\n                 '--LSTMUnits 64 '\r\n                 '--GALUnits 64 '\r\n                 '--GALHeads 2 '\r\n                 '--DenseUnits 32 '\r\n                 '--DataRange All '\r\n                 '--TrainDays All '\r\n                 '--TC 0.7 '\r\n                 '--TD 5000 '\r\n                 # '--TI 30 '\r\n                 '--Epoch 10000 '\r\n                 '--Train False '\r\n                 '--lr 2e-5 '\r\n                 '--Normalize True '\r\n                 '--patience 0.1 '\r\n                 '--ESlength 500 '\r\n                 '--BatchSize 128 '\r\n                 '--Device 1 ')\r\n\r\nif __name__ == \"__main__\":\r\n\r\n    # 可以先选择在 DiDi-Xian, DiDi-Chengdu, Metro-Shanghai, ChargeStation-Beijing 这几个数据集上进行测试，因为耗时比较短\r\n\r\n    # stability test\r\n    test_times = 10\r\n    for i in range(test_times):\r\n        os.system(shared_params + '--CT 6 --PT 7 --TT 4 --City ShanghaiV1 --Group Shanghai'\r\n                                  ' --K 1 --L 1 --Graph Distance-line-Correlation --CodeVersion ST_Sim_%s' % i)"
  },
  {
    "path": "Experiments/V3_GACN/GACN_Master.py",
    "content": "import os\r\n\r\nimport warnings\r\nwarnings.filterwarnings(\"ignore\")\r\n\r\nshared_params_gacn = ('python V3_GACN.py '\r\n                      '--K 1 '\r\n                      '--L 1 '\r\n                      '--Graph Correlation '\r\n                      '--DenseUnits 32 '\r\n                      '--DataRange All '\r\n                      '--TrainDays All '\r\n                      '--TC 0 '\r\n                      '--TD 1000 '\r\n                      '--TI 500 '\r\n                      '--Epoch 10000 '\r\n                      '--Train True '\r\n                      '--ESlength 50 '\r\n                      '--patience 0.1 '\r\n                      '--BatchSize 16 '\r\n                      '--Device 1')\r\n\r\n\r\nif __name__ == \"__main__\":\r\n\r\n    # os.system(shared_params_gacn + ' --Dataset Bike --City Chicago --Group Chicago'\r\n    #                                ' --lr 5e-5 --T 6 --GALLayers 4 --GALHeads 2 --GALUnits 32 --CodeVersion T6')\r\n\r\n    os.system(shared_params_gacn + ' --Dataset Bike --City Chicago --Group Chicago'\r\n                                   ' --lr 1e-4 --T 12 --GALLayers 4 --GALHeads 2 --GALUnits 32 --CodeVersion T12')"
  },
  {
    "path": "Experiments/V3_GACN/GACN_Obj.py",
    "content": "import os\r\n\r\nfrom UCTB.dataset import NodeTrafficLoader\r\nfrom UCTB.model import GACN\r\nfrom UCTB.evaluation import metric\r\n\r\nfrom Experiments.utils import model_dir_path\r\n\r\n\r\ndef gacn_param_parser():\r\n    import argparse\r\n    parser = argparse.ArgumentParser(description=\"Argument Parser\")\r\n    # data source\r\n    parser.add_argument('--Dataset', default='Metro')\r\n    parser.add_argument('--City', default='ShanghaiV1')\r\n    # network parameter\r\n    parser.add_argument('--T', default='6', type=int)\r\n    parser.add_argument('--K', default='0')\r\n    parser.add_argument('--L', default='1')\r\n    parser.add_argument('--Graph', default='Correlation')\r\n    parser.add_argument('--GALLayers', default='4', type=int)\r\n    parser.add_argument('--GALUnits', default='32', type=int)\r\n    parser.add_argument('--GALHeads', default='2', type=int)\r\n    parser.add_argument('--DenseUnits', default='32', type=int)\r\n    # Training data parameters\r\n    parser.add_argument('--DataRange', default='All')\r\n    parser.add_argument('--TrainDays', default='All')\r\n    # Graph parameter\r\n    parser.add_argument('--TC', default='0', type=float)\r\n    parser.add_argument('--TD', default='1000', type=float)\r\n    parser.add_argument('--TI', default='500', type=float)\r\n    # training parameters\r\n    parser.add_argument('--Epoch', default='5000', type=int)\r\n    parser.add_argument('--Train', default='True')\r\n    parser.add_argument('--lr', default='1e-4', type=float)\r\n    parser.add_argument('--ESlength', default='500', type=int)\r\n    parser.add_argument('--patience', default='0.1', type=float)\r\n    parser.add_argument('--BatchSize', default='64', type=int)\r\n    # device parameter\r\n    parser.add_argument('--Device', default='0', type=str)\r\n    # version control\r\n    parser.add_argument('--Group', default='Debug')\r\n    parser.add_argument('--CodeVersion', default='Shanghai_GACN2')\r\n    return parser\r\n\r\n\r\nparser = gacn_param_parser()\r\nargs = parser.parse_args()\r\n\r\nmodel_dir = os.path.join(model_dir_path, args.Group)\r\n\r\ncode_version = 'GACN_{}_K{}L{}_{}'.format(''.join([e[0] for e in args.Graph.split('-')]),\r\n                                          args.K, args.L, args.CodeVersion)\r\n\r\n# Config data loader\r\ndata_loader = NodeTrafficLoader(dataset=args.Dataset, city=args.City,\r\n                                data_range=args.DataRange, train_data_length=args.TrainDays, test_ratio=0.1,\r\n                                normalize=True,\r\n                                T=args.T, TI=args.TI, TD=args.TD, TC=args.TC, graph=args.Graph, with_lm=True)\r\n\r\nde_normalizer = data_loader.normalizer.min_max_denormal\r\n\r\nGACN_Obj = GACN(num_node=data_loader.station_number,\r\n                input_dim=1,\r\n                time_embedding_dim=data_loader.tpe_position_index.shape[-1],\r\n                external_feature_dim=data_loader.external_dim,\r\n                T=int(args.T),\r\n                gcl_k=int(args.K),\r\n                gcl_layers=int(args.L),\r\n                gal_layers=int(args.GALLayers),\r\n                gal_units=int(args.GALUnits),\r\n                gal_num_heads=int(args.GALHeads),\r\n                dense_units=int(args.DenseUnits),\r\n                lr=float(args.lr),\r\n                code_version=code_version,\r\n                model_dir=model_dir,\r\n                gpu_device=args.Device)\r\n\r\nGACN_Obj.build()\r\n\r\n# # Training\r\nif args.Train == 'True':\r\n    GACN_Obj.fit(input=data_loader.train_x,\r\n                 laplace_matrix=data_loader.LM[0],\r\n                 target=data_loader.train_y,\r\n                 time_embedding=data_loader.tpe_position_index,\r\n                 external_input=data_loader.train_ef,\r\n                 batch_size=int(args.BatchSize),\r\n                 max_epoch=int(args.Epoch),\r\n                 early_stop_method='t-test',\r\n                 early_stop_length=int(args.ESlength),\r\n                 early_stop_patience=float(args.patience))\r\n\r\nGACN_Obj.load(code_version)\r\n\r\n# Evaluate\r\ntest_rmse = GACN_Obj.evaluate(input=data_loader.test_x,\r\n                              laplace_matrix=data_loader.LM[0],\r\n                              target=data_loader.test_y,\r\n                              time_embedding=data_loader.tpe_position_index,\r\n                              external_input=data_loader.test_ef,\r\n                              cache_volume=4,\r\n                              metrics=[metric.rmse],\r\n                              de_normalizer=de_normalizer,\r\n                              threshold=0)\r\n\r\nprint('Test result', test_rmse)"
  },
  {
    "path": "Experiments/XGBoost/XGBoost.py",
    "content": "import numpy as np\nimport argparse\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import XGBoost\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess import SplitData\nimport nni\nimport os\n\nparams = {\n    'CT': 12,\n    'PT': 6,\n    'TT': 4,\n    'max_depth': 8,\n    'num_boost_round': 51\n}\n\nparser = argparse.ArgumentParser(description=\"Argument Parser\")\n# data source\nparser.add_argument('--dataset', default='Metro', type=str)\nparser.add_argument('--city', default=\"Chongqing\", type=str)\nparser.add_argument('--MergeIndex', default=3)\nparser.add_argument('--DataRange', default=\"all\")\nparser.add_argument('--TrainDays', default=\"all\")\nparser.add_argument('--MergeWay', default=\"sum\")\nparser.add_argument('--test_ratio', default=0.1, type=float)\n\n#use params and args to show its difference\nargs = vars(parser.parse_args())\n\n\nparams.update(nni.get_next_parameter())\n\ndata_loader = NodeTrafficLoader(dataset=args[\"dataset\"], city=args['city'], closeness_len=int(params['CT']), period_len=int(params['PT']), trend_len=int(params['TT']),\n                                data_range=args['DataRange'], train_data_length=args['TrainDays'],\n                                test_ratio=args['test_ratio'],\n                                with_lm=False, normalize=False, MergeIndex=args['MergeIndex'],\n                                MergeWay=args['MergeWay'])\n\ntrain_closeness, val_closeness = SplitData.split_data(\n    data_loader.train_closeness, [0.9, 0.1])\ntrain_period, val_period = SplitData.split_data(\n    data_loader.train_period, [0.9, 0.1])\ntrain_trend, val_trend = SplitData.split_data(\n    data_loader.train_trend, [0.9, 0.1])\n\ntrain_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\n\nprediction_test = []\nprediction_val = []\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = XGBoost(n_estimators=int(\n        params['num_boost_round']), max_depth=int(params['max_depth']))\n\n    X_Train = []\n    X_Val = []\n    X_Test = []\n    if int(params['CT']) > 0:\n        X_Train.append(train_closeness[:, i, :, 0])\n        X_Val.append(val_closeness[:, i, :, 0])\n        X_Test.append(data_loader.test_closeness[:, i, :, 0])\n    if int(params['PT']) > 0:\n        X_Train.append(train_period[:, i, :, 0])\n        X_Val.append(val_period[:, i, :, 0])\n        X_Test.append(data_loader.test_period[:, i, :, 0])\n    if int(params['TT']) > 0:\n        X_Train.append(train_trend[:, i, :, 0])\n        X_Val.append(val_trend[:, i, :, 0])\n        X_Test.append(data_loader.test_trend[:, i, :, 0])\n\n    X_Train = np.concatenate(X_Train, axis=-1)\n    X_Val = np.concatenate(X_Val, axis=-1)\n    X_Test = np.concatenate(X_Test, axis=-1)\n\n    model.fit(X_Train, train_y[:, i, 0])\n\n    p_val = model.predict(X_Val)\n    p_test = model.predict(X_Test)\n\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\n    prediction_val.append(p_val.reshape([-1, 1, 1]))\n\nprediction_test = np.concatenate(prediction_test, axis=-2)\nprediction_val = np.concatenate(prediction_val, axis=-2)\n\nprint('Val RMSE', metric.rmse(prediction_val, val_y))\nprint('Test RMSE', metric.rmse(prediction_test, data_loader.test_y))\n\n\n\nnni.report_final_result({'default': metric.rmse(prediction_val, val_y),\n                         'test-rmse': metric.rmse(prediction_test, data_loader.test_y)})\n"
  },
  {
    "path": "Experiments/XGBoost/xgboost_config.yml",
    "content": "authorName: lychen\nexperimentName: xgboost_parameter_search\ntrialConcurrency: 2\nmaxExecDuration: 24h\nmaxTrialNum: 200\ntrainingServicePlatform: local\n# The path to Search Space\nsearchSpacePath: xgboost_search_space.json\nuseAnnotation: false\ntuner:\n  builtinTunerName: TPE\n# The path and the running command of trial\ntrial:\n  # python XGBoost.py --dataset Metro --city Chongqing --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays all\n  # python XGBoost.py --dataset DiDi --city Xian --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays all\n  # python XGBoost.py --dataset Bike --city NYC --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays 365\n  # python XGBoost.py --dataset ChargeStation --city Beijing --MergeIndex 1 --MergeWay max --DataRange all --TrainDays all\n  # python XGBoost.py --dataset Taxi --city BJ --MergeIndex 2 --MergeWay sum --DataRange all --TrainDays all\n  # python XGBoost.py --dataset METR --city LA --MergeIndex 3 --MergeWay average --DataRange all --TrainDays all --test_ratio 0.2\n  # python XGBoost.py --dataset PEMS --city BAY --MergeIndex 3 --MergeWay average --DataRange all --TrainDays all --test_ratio 0.2\n  # python XGBoost.py --dataset Metro --city Shanghai --MergeIndex 6 --DataRange all --TrainDays all\n  command: python XGBoost.py --dataset DiDi --city Xian_Street --MergeIndex 12 --MergeWay sum --DataRange all --TrainDays all\n  codeDir: .\n  gpuNum: 0"
  },
  {
    "path": "Experiments/XGBoost/xgboost_search_space.json",
    "content": "{\n\n    \"CT\": {\"_type\": \"randint\", \"_value\": [0,13]},\n    \"PT\": {\"_type\": \"randint\", \"_value\": [0,15]},\n    \"TT\": {\"_type\": \"randint\", \"_value\": [0,5]},\n\n    \"max_depth\": {\"_type\":\"randint\",\"_value\":[2, 11]},\n    \"num_boost_round\": {\"_type\":\"randint\",\"_value\":[10, 201]}\n}"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) [2019] [fullname]\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "QuickStarts/ARIMA.py",
    "content": "import numpy as np\n\nfrom UCTB.model import ARIMA\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=24, period_len=0, trend_len=0,\n                                with_lm=False, normalize=False)\n\ntest_prediction_collector = []\nfor i in range(data_loader.station_number):\n    try:\n        model_obj = ARIMA(time_sequence=data_loader.train_closeness[:, i, -1, 0],\n                          order=[6, 0, 1], seasonal_order=[0, 0, 0, 0])\n        test_prediction = model_obj.predict(time_sequences=data_loader.test_closeness[:, i, :, 0],\n                                            forecast_step=1)\n    except Exception as e:\n        print('Converge failed with error', e)\n        print('Using last as prediction')\n        test_prediction = data_loader.test_closeness[:, i, -1:, :]\n    test_prediction_collector.append(test_prediction)\n    print('Station', i, 'finished')\n\ntest_rmse = metric.rmse(np.concatenate(test_prediction_collector, axis=-2), data_loader.test_y)\n\nprint('test_rmse', test_rmse)"
  },
  {
    "path": "QuickStarts/DCRNN.py",
    "content": "import numpy as np\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import DCRNN\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n\n\nclass my_data_loader(NodeTrafficLoader):\n\n    def __init__(self, **kwargs):\n\n        super(my_data_loader, self).__init__(**kwargs)\n\n        # generate LM\n        graph_obj = GraphGenerator(graph=kwargs['graph'], data_loader=self)\n        self.AM = graph_obj.AM\n        self.LM = graph_obj.LM\n\n    def diffusion_matrix(self, filter_type='random_walk'):\n        def calculate_random_walk_matrix(adjacent_mx):\n            d = np.array(adjacent_mx.sum(1))\n            d_inv = np.power(d, -1).flatten()\n            d_inv[np.isinf(d_inv)] = 0.\n            d_mat_inv = np.diag(d_inv)\n            random_walk_mx = d_mat_inv.dot(adjacent_mx)\n            return random_walk_mx\n\n        assert len(self.AM) == 1\n\n        diffusion_matrix = []\n        if filter_type == \"random_walk\":\n            diffusion_matrix.append(calculate_random_walk_matrix(self.AM[0]).T)\n        elif filter_type == \"dual_random_walk\":\n            diffusion_matrix.append(calculate_random_walk_matrix(self.AM[0]).T)\n            diffusion_matrix.append(calculate_random_walk_matrix(self.AM[0].T).T)\n        return np.array(diffusion_matrix, dtype=np.float32)\n\n\ndata_loader = my_data_loader(dataset='Bike', city='NYC', train_data_length='365',\n                             closeness_len=6, period_len=7, trend_len=4, graph='Correlation', normalize=True)\n\ndiffusion_matrix = data_loader.diffusion_matrix()\n\nbatch_size = 64\n\nDCRNN_Obj = DCRNN(num_node=data_loader.station_number,\n                  num_diffusion_matrix=diffusion_matrix.shape[0],\n                  num_rnn_units=64,\n                  num_rnn_layers=1,\n                  max_diffusion_step=2,\n                  seq_len=data_loader.closeness_len + data_loader.period_len + data_loader.trend_len,\n                  use_curriculum_learning=False,\n                  input_dim=1,\n                  output_dim=1,\n                  cl_decay_steps=1000,\n                  target_len=1,\n                  lr=1e-4,\n                  epsilon=1e-3,\n                  optimizer_name='Adam',\n                  code_version='DCRNN-QuickStart',\n                  model_dir='model_dir',\n                  gpu_device='0')\n\n# Build tf-graph\nDCRNN_Obj.build()\n\nprint('Number of trainable parameters', DCRNN_Obj.trainable_vars)\n\n# Training\nDCRNN_Obj.fit(inputs=np.concatenate((data_loader.train_trend.transpose([0, 2, 1, 3]),\n                                     data_loader.train_period.transpose([0, 2, 1, 3]),\n                                     data_loader.train_closeness.transpose([0, 2, 1, 3])), axis=1),\n              diffusion_matrix=diffusion_matrix,\n              target=data_loader.train_y.reshape([-1, 1, data_loader.station_number, 1]),\n              batch_size=batch_size,\n              sequence_length=data_loader.train_sequence_len)\n\n# Predict\nprediction = DCRNN_Obj.predict(inputs=np.concatenate((data_loader.test_trend.transpose([0, 2, 1, 3]),\n                                                      data_loader.test_period.transpose([0, 2, 1, 3]),\n                                                      data_loader.test_closeness.transpose([0, 2, 1, 3])), axis=1),\n                               diffusion_matrix=diffusion_matrix,\n                               target=data_loader.test_y.reshape([-1, 1, data_loader.station_number, 1]),\n                               sequence_length=data_loader.test_sequence_len,\n                               output_names=['prediction'])\n\n# Evaluate\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.min_max_denormal(prediction['prediction']),\n                                 target=data_loader.normalizer.min_max_denormal(\n                                     data_loader.test_y.transpose([0, 2, 1]))))"
  },
  {
    "path": "QuickStarts/DeepST.py",
    "content": "from UCTB.dataset import GridTrafficLoader\nfrom UCTB.model import DeepST\nfrom UCTB.evaluation import metric\n\n# Config data loader\ndata_loader = GridTrafficLoader(dataset='Bike', city='NYC', closeness_len=6, period_len=7, trend_len=4)\n\ndeep_st_obj = DeepST(closeness_len=data_loader.closeness_len,\n                     period_len=data_loader.period_len,\n                     trend_len=data_loader.trend_len,\n                     external_dim=data_loader.external_dim,\n                     width=data_loader.width, height=data_loader.height,\n                     lr=1e-5)\n\ndeep_st_obj.build()\n\nprint('Trainable variables', deep_st_obj.trainable_vars)\n\n# Training\ndeep_st_obj.fit(closeness_feature=data_loader.train_closeness,\n                period_feature=data_loader.train_period,\n                trend_feature=data_loader.train_trend,\n                target=data_loader.train_y,\n                external_feature=data_loader.train_ef,\n                sequence_length=data_loader.train_sequence_len,\n                validate_ratio=0.1)\n\n# Predict\nprediction = deep_st_obj.predict(closeness_feature=data_loader.test_closeness,\n                                 period_feature=data_loader.test_period,\n                                 trend_feature=data_loader.test_trend,\n                                 target=data_loader.test_y,\n                                 external_feature=data_loader.test_ef,\n                                 sequence_length=data_loader.test_sequence_len)\n\n# Compute metric\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.min_max_denormal(prediction['prediction']),\n                                 target=data_loader.normalizer.min_max_denormal(data_loader.test_y)))\n"
  },
  {
    "path": "QuickStarts/GBRT.py",
    "content": "import numpy as np\n\nfrom sklearn.ensemble import GradientBoostingRegressor\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\ncloseness_len = 6\nperiod_len = 7\ntrend_len = 4\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC',\n                                closeness_len=closeness_len, period_len=period_len, trend_len=trend_len,\n                                with_lm=False, normalize=False)\n\nprediction = []\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = GradientBoostingRegressor(n_estimators=100, max_depth=3)\n\n    X_Train = []\n    X_Test = []\n    if closeness_len > 0:\n        X_Train.append(data_loader.train_closeness[:, i, :, 0])\n        X_Test.append(data_loader.test_closeness[:, i, :, 0])\n    if period_len > 0:\n        X_Train.append(data_loader.train_period[:, i, :, 0])\n        X_Test.append(data_loader.test_period[:, i, :, 0])\n    if trend_len > 0:\n        X_Train.append(data_loader.train_trend[:, i, :, 0])\n        X_Test.append(data_loader.test_trend[:, i, :, 0])\n\n    X_Train = np.concatenate(X_Train, axis=-1)\n    X_Test = np.concatenate(X_Test, axis=-1)\n\n    model.fit(X_Train, data_loader.train_y[:, i, 0])\n\n    p = model.predict(X_Test)\n\n    prediction.append(p.reshape([-1, 1, 1]))\n\nprediction = np.concatenate(prediction, axis=-2)\n\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))"
  },
  {
    "path": "QuickStarts/GeoMAN.py",
    "content": "from UCTB.dataset import NodeTrafficLoader\nfrom UCTB.preprocess import MoveSample\nfrom UCTB.model import GeoMAN\nfrom UCTB.evaluation import metric\nimport numpy as np\nimport time\n\n\nclass GeoMAN_DataLoader(NodeTrafficLoader):\n    def __init__(self, input_steps=12, output_steps=1, **kwargs):\n        \"\"\"A wrapper of ``NodeTrafficLoader`` to make its data form compatible with GeoMAN's inputs.\n\n        Args:\n            input_steps (int): The length of historical input data, a.k.a, input timesteps. Default: 12\n            output_steps (int): The number of steps that need prediction by one piece of history data, a.k.a,\n                output timesteps. Have to be 1 now. Default: 1\n            **kwargs (dict): Used to pass other parameters to class ``NodeTrafficLoader``.\n\n        Attributes:\n            train_local_features (list): A list, where each element corresponds to the ``local_features`` in GeoMAN's\n                feed dict of one sensor (node)  and the length of list is ``station_number``. Uses indexes of it to\n                specify a target sensor, e.g., ``train_local_features[i]`` for sensor ``i``.\n            train_local_attn_states (list): A list containing each sensor's ``local_attn_states``\n            train_y (list): A list containing each sensor's label ndarray.\n            train_seq_len (int): The total sample number of training data set, which will be used in mini-batch training.\n        \"\"\"\n        super(GeoMAN_DataLoader, self).__init__(closeness_len=input_steps,\n                                                period_len=input_steps,\n                                                trend_len=input_steps,\n                                                target_length=output_steps,\n                                                **kwargs)\n        self.input_steps = input_steps\n        self.output_steps = output_steps\n        self.move_ef = MoveSample(input_steps, 0, 0, output_steps)\n\n        self.train_local_features, self.train_global_features, self.train_local_attn_states, self.train_global_attn_states, self.train_external_features, self.train_y = self.process_data(\n            self.train_trend, self.train_period, self.train_closeness, self.train_ef, self.train_y)\n\n        self.test_local_features, self.test_global_features, self.test_local_attn_states, self.test_global_attn_states, self.test_external_features, self.test_y = self.process_data(\n            self.test_trend, self.test_period, self.test_closeness, self.test_ef, self.test_y)\n        self.input_dim = self.train_local_features[0].shape[-1]\n        self.output_dim = self.train_y[0].shape[-1]\n        self.train_seq_len = self.train_external_features.shape[0]\n        self.test_seq_len = self.test_external_features.shape[0]\n\n    def process_data(self, trend, period, closeness, ef, y):\n        \"\"\"Process features to GeoMAN's acceptable forms\n\n        Different from other models, GeoMAN needs all the inputs that have the same timesteps, so we generate\n        ``closeness``, ``period`` and ``trend`` from a fixed length. After that, we simply concatenate these three\n        features into a single matrix ``global_attn_states``. Based on it, we can eventually construct all the inputs\n        of GeoMAN, including ``local_features``, ``global_features``, ``local_attn_states`` and\n        ``global_attn_states``. Moreover, since the original eternal features in ``NodeTrafficLoader`` are timeless,\n        we handle them with ``move_ef`` to generate timesteps as a workaround.\n\n        \"\"\"\n        # apply timestep to external features, which will make its length shorter\n        _, ext_features = self.move_ef.general_move_sample(ef)\n        seq_len = ext_features.shape[0]\n\n        global_attn_states = [d[:seq_len] for d in [closeness, period, trend]]  # clip length to align\n\n        global_features = global_attn_states[0]  # target to predict is closeness\n        global_features = global_features.transpose([0, 2, 1, 3])\n        global_features = global_features.reshape(-1, self.input_steps,\n                                                  self.station_number)  # (batch_size, n_steps_encoder, n_sensors)\n        global_attn_states = np.concatenate(global_attn_states, axis=3)\n        local_features = np.split(global_attn_states, self.station_number,\n                                  axis=1)  # [(batch_size, n_steps_encoder, ), ...] list of nodes\n        local_features = [d.squeeze(1) for d in local_features]\n        global_attn_states = global_attn_states.transpose(\n            [0, 1, 3, 2])  # (batch_size, n_sensors, n_input_encoder, n_steps_encoder)\n        local_attn_states = np.split(global_attn_states, self.station_number,\n                                     axis=1)  # [(batch_size, n_input_encoder, n_steps_encoder)\n        local_attn_states = [d.squeeze(1) for d in local_attn_states]\n\n        y = np.split(y[:seq_len], self.station_number, axis=1)\n        return local_features, global_features, local_attn_states, global_attn_states, ext_features, y\n\n\ndata_loader = GeoMAN_DataLoader(dataset='Bike', city='NYC', input_steps=12, output_steps=1)\nmodel = GeoMAN(total_sensers=data_loader.station_number,\n               input_dim=data_loader.input_dim,\n               external_dim=data_loader.external_dim,\n               output_dim=data_loader.output_dim,\n               input_steps=data_loader.input_steps,\n               output_steps=data_loader.output_steps)\nmodel.build()\n# training and evaluation\nresults = []\nfor node in range(data_loader.station_number):\n    each_time = time.time()\n    model._code_version = str(node)  # to train different model for different node\n    model.fit(local_features=data_loader.train_local_features[node],\n              global_features=data_loader.train_global_features,\n              local_attn_states=data_loader.train_local_attn_states[node],\n              global_attn_states=data_loader.train_global_attn_states,\n              external_features=data_loader.train_external_features,\n              targets=data_loader.train_y[node],\n              sequence_length=data_loader.train_seq_len)\n\n    pred = model.predict(local_features=data_loader.test_local_features[node],\n                         global_features=data_loader.test_global_features,\n                         local_attn_states=data_loader.test_local_attn_states[node],\n                         global_attn_states=data_loader.test_global_attn_states,\n                         external_features=data_loader.test_external_features,\n                         targets=data_loader.test_y[node],\n                         sequence_length=data_loader.test_seq_len)\n    results.append(metric.rmse(pred['prediction'], data_loader.test_y[node]))\n    seconds = int(time.time() - each_time)\n    print('[Node {}] - {}s - RMSE: {}'.format(node, seconds, results[-1]))\n\n    # randomize weights again for next node\n    model._session.run(model._variable_init)\n\nprint('Overall average RMSE: {}'.format(np.mean(results)))\n"
  },
  {
    "path": "QuickStarts/GraphWaveNet.py",
    "content": "from UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model.GraphWaveNet import gwnet\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n# Config data loader\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC',\n                                closeness_len=6, period_len=7, trend_len=4, normalize=True)\n\n# Build Graph\ngraph_obj = GraphGenerator(graph='Correlation', data_loader=data_loader)\n\n# Init model object\nSTMeta_Obj = STMeta(closeness_len=data_loader.closeness_len,\n                    period_len=data_loader.period_len,\n                    trend_len=data_loader.trend_len,\n                    num_node=data_loader.station_number,\n                    num_graph=graph_obj.LM.shape[0],\n                    external_dim=data_loader.external_dim)\n\n# Build tf-graph\nSTMeta_Obj.build()\n# Training\nSTMeta_Obj.fit(closeness_feature=data_loader.train_closeness,\n               period_feature=data_loader.train_period,\n               trend_feature=data_loader.train_trend,\n               laplace_matrix=graph_obj.LM,\n               target=data_loader.train_y,\n               external_feature=data_loader.train_ef,\n               sequence_length=data_loader.train_sequence_len)\n\n# Predict\nprediction = STMeta_Obj.predict(closeness_feature=data_loader.test_closeness,\n                                period_feature=data_loader.test_period,\n                                trend_feature=data_loader.test_trend,\n                                laplace_matrix=graph_obj.LM,\n                                target=data_loader.test_y,\n                                external_feature=data_loader.test_ef,\n                                output_names=['prediction'],\n                                sequence_length=data_loader.test_sequence_len)\n\n# Evaluate\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.min_max_denormal(prediction['prediction']),\n                                 target=data_loader.normalizer.min_max_denormal(data_loader.test_y)))\n"
  },
  {
    "path": "QuickStarts/HM.py",
    "content": "from UCTB.dataset import NodeTrafficLoader\r\nfrom UCTB.model import HM\r\nfrom UCTB.evaluation import metric\r\nfrom UCTB.utils import save_predict_in_dataset\r\n\r\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=0, period_len=0, trend_len=4,\r\n                                with_lm=False, normalize=False)\r\n\r\nhm_obj = HM(c=data_loader.closeness_len,\r\n            p=data_loader.period_len, t=data_loader.trend_len)\r\n\r\nprediction = hm_obj.predict(closeness_feature=data_loader.test_closeness,\r\n                            period_feature=data_loader.test_period,\r\n                            trend_feature=data_loader.test_trend)\r\n\r\n#save_predict_in_dataset(data_loader, prediction, \"HM\")\r\n\r\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))\r\n"
  },
  {
    "path": "QuickStarts/HMM.py",
    "content": "import numpy as np\r\n\r\nfrom UCTB.dataset import NodeTrafficLoader\r\nfrom UCTB.model import HMM\r\nfrom UCTB.evaluation import metric\r\n\r\ndata_loader = NodeTrafficLoader(dataset='Bike', city='Chicago',\r\n                                closeness_len=12, period_len=0, trend_len=0,\r\n                                with_lm=False, normalize=False)\r\n\r\nprediction = []\r\nfor station_index in range(data_loader.station_number):\r\n    # train the hmm model\r\n    try:\r\n        hmm = HMM(num_components=8, n_iter=100)\r\n        hmm.fit(data_loader.train_closeness[:, station_index:station_index+1, -1, 0])\r\n        # predict\r\n        p = []\r\n        for time_index in range(data_loader.test_closeness.shape[0]):\r\n            p.append(hmm.predict(data_loader.test_closeness[time_index, station_index, :, :], length=1))\r\n    except Exception as e:\r\n        print('Failed at station', station_index, 'with error', e)\r\n        # using zero as prediction\r\n        p = [[[0]] for _ in range(data_loader.test_closeness.shape[0])]\r\n\r\n    prediction.append(np.array(p)[:, :, 0])\r\n    print('Node', station_index, 'finished')\r\n\r\nprediction = np.array(prediction).transpose([1, 0, 2])\r\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))"
  },
  {
    "path": "QuickStarts/STMeta.py",
    "content": "from UCTB.dataset import NodeTrafficLoader\r\nfrom UCTB.model import STMeta\r\nfrom UCTB.evaluation import metric\r\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\r\n# Config data loader\r\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC',\r\n                                closeness_len=6, period_len=7, trend_len=4, normalize=True)\r\n\r\n# Build Graph\r\ngraph_obj = GraphGenerator(graph='Correlation', data_loader=data_loader)\r\n\r\n# Init model object\r\nSTMeta_Obj = STMeta(closeness_len=data_loader.closeness_len,\r\n                    period_len=data_loader.period_len,\r\n                    trend_len=data_loader.trend_len,\r\n                    num_node=data_loader.station_number,\r\n                    num_graph=graph_obj.LM.shape[0],\r\n                    external_dim=data_loader.external_dim)\r\n\r\n# Build tf-graph\r\nSTMeta_Obj.build()\r\n# Training\r\nSTMeta_Obj.fit(closeness_feature=data_loader.train_closeness,\r\n               period_feature=data_loader.train_period,\r\n               trend_feature=data_loader.train_trend,\r\n               laplace_matrix=graph_obj.LM,\r\n               target=data_loader.train_y,\r\n               external_feature=data_loader.train_ef,\r\n               sequence_length=data_loader.train_sequence_len)\r\n\r\n# Predict\r\nprediction = STMeta_Obj.predict(closeness_feature=data_loader.test_closeness,\r\n                                period_feature=data_loader.test_period,\r\n                                trend_feature=data_loader.test_trend,\r\n                                laplace_matrix=graph_obj.LM,\r\n                                target=data_loader.test_y,\r\n                                external_feature=data_loader.test_ef,\r\n                                output_names=['prediction'],\r\n                                sequence_length=data_loader.test_sequence_len)\r\n\r\n# Evaluate\r\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.min_max_denormal(prediction['prediction']),\r\n                                 target=data_loader.normalizer.min_max_denormal(data_loader.test_y)))\r\n"
  },
  {
    "path": "QuickStarts/ST_ResNet.py",
    "content": "from UCTB.dataset import GridTrafficLoader\nfrom UCTB.model import ST_ResNet\nfrom UCTB.evaluation import metric\n\n# Config data loader\ndata_loader = GridTrafficLoader(dataset='Bike', city='Chicago', closeness_len=6, period_len=7, trend_len=4)\n\nST_ResNet_Obj = ST_ResNet(closeness_len=data_loader.closeness_len,\n                          period_len=data_loader.period_len,\n                          trend_len=data_loader.trend_len,\n                          external_dim=data_loader.external_dim,\n                          width=data_loader.width, height=data_loader.height)\n\nST_ResNet_Obj.build()\n\nprint(ST_ResNet_Obj.trainable_vars)\n\n# Training\nST_ResNet_Obj.fit(closeness_feature=data_loader.train_closeness,\n                  period_feature=data_loader.train_period,\n                  trend_feature=data_loader.train_trend,\n                  target=data_loader.train_y,\n                  external_feature=data_loader.train_ef,\n                  sequence_length=data_loader.train_sequence_len,\n                  validate_ratio=0.1)\n\n# Predict\nprediction = ST_ResNet_Obj.predict(closeness_feature=data_loader.test_closeness,\n                                   period_feature=data_loader.test_period,\n                                   trend_feature=data_loader.test_trend,\n                                   target=data_loader.test_y,\n                                   external_feature=data_loader.test_ef,\n                                   sequence_length=data_loader.test_sequence_len)\n\n# Compute metric\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.min_max_denormal(prediction['prediction']),\n                                 target=data_loader.normalizer.min_max_denormal(data_loader.test_y)))"
  },
  {
    "path": "QuickStarts/Visualization.py",
    "content": "from UCTB.dataset import NodeTrafficLoader\r\n#from UCTB.utils import st_map\r\n\r\nfrom dateutil.parser import parse\r\n\r\n# Config data loader\r\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', with_lm=False)\r\n\r\ndata_loader.st_map()"
  },
  {
    "path": "QuickStarts/XGBoost.py",
    "content": "import numpy as np\r\n\r\nfrom UCTB.dataset import NodeTrafficLoader\r\nfrom UCTB.model import XGBoost\r\nfrom UCTB.evaluation import metric\r\n\r\ndata_loader = NodeTrafficLoader(dataset='Bike', city='DC', closeness_len=6, period_len=7, trend_len=4,\r\n                                with_lm=False, normalize=False)\r\n\r\nprediction_test = []\r\n\r\nfor i in range(data_loader.station_number):\r\n\r\n    print('*************************************************************')\r\n    print('Station', i)\r\n\r\n    model = XGBoost(n_estimators=100, max_depth=3, objective='reg:squarederror')\r\n\r\n    model.fit(np.concatenate((data_loader.train_closeness[:, i, :, 0],\r\n                              data_loader.train_period[:, i, :, 0],\r\n                              data_loader.train_trend[:, i, :, 0],), axis=-1),\r\n              data_loader.train_y[:, i, 0])\r\n\r\n    p_test = model.predict(np.concatenate((data_loader.test_closeness[:, i, :, 0],\r\n                                           data_loader.test_period[:, i, :, 0],\r\n                                           data_loader.test_trend[:, i, :, 0],), axis=-1))\r\n\r\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\r\n\r\nprediction_test = np.concatenate(prediction_test, axis=-2)\r\n\r\nprint('Test RMSE', metric.rmse(prediction_test, data_loader.test_y))"
  },
  {
    "path": "QuickStarts/XGBoost_Validate.py",
    "content": "import numpy as np\r\n\r\nfrom UCTB.dataset import NodeTrafficLoader\r\nfrom UCTB.model import XGBoost\r\nfrom UCTB.evaluation import metric\r\nfrom UCTB.preprocess import SplitData\r\n\r\ncloseness_len = 6\r\nperiod_len = 7\r\ntrend_len = 4\r\n\r\ndata_loader = NodeTrafficLoader(dataset='Bike', city='DC',\r\n                                closeness_len=closeness_len, period_len=period_len, trend_len=trend_len,\r\n                                with_lm=False, normalize=False)\r\n\r\ntrain_closeness, val_closeness = SplitData.split_data(data_loader.train_closeness, [0.9, 0.1])\r\ntrain_period, val_period = SplitData.split_data(data_loader.train_period, [0.9, 0.1])\r\ntrain_trend, val_trend = SplitData.split_data(data_loader.train_trend, [0.9, 0.1])\r\n\r\ntrain_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\r\n\r\nprediction_test = []\r\nprediction_val = []\r\n\r\nfor i in range(data_loader.station_number):\r\n\r\n    print('*************************************************************')\r\n    print('Station', i)\r\n\r\n    model = XGBoost(n_estimators=100, max_depth=3, objective='reg:linear')\r\n\r\n    X_Train = []\r\n    X_Val = []\r\n    X_Test = []\r\n    if closeness_len > 0:\r\n        X_Train.append(train_closeness[:, i, :, 0])\r\n        X_Val.append(val_closeness[:, i, :, 0])\r\n        X_Test.append(data_loader.test_closeness[:, i, :, 0])\r\n    if period_len > 0:\r\n        X_Train.append(train_period[:, i, :, 0])\r\n        X_Val.append(val_period[:, i, :, 0])\r\n        X_Test.append(data_loader.test_period[:, i, :, 0])\r\n    if trend_len > 0:\r\n        X_Train.append(train_trend[:, i, :, 0])\r\n        X_Val.append(val_trend[:, i, :, 0])\r\n        X_Test.append(data_loader.test_trend[:, i, :, 0])\r\n\r\n    X_Train = np.concatenate(X_Train, axis=-1)\r\n    X_Val = np.concatenate(X_Val, axis=-1)\r\n    X_Test = np.concatenate(X_Test, axis=-1)\r\n\r\n    model.fit(X_Train, train_y[:, i, 0])\r\n\r\n    p_val = model.predict(X_Val)\r\n    p_test = model.predict(X_Test)\r\n\r\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\r\n    prediction_val.append(p_val.reshape([-1, 1, 1]))\r\n\r\nprediction_test = np.concatenate(prediction_test, axis=-2)\r\nprediction_val = np.concatenate(prediction_val, axis=-2)\r\n\r\nprint('Val RMSE', metric.rmse(prediction_val, val_y))\r\nprint('Test RMSE', metric.rmse(prediction_test, data_loader.test_y))"
  },
  {
    "path": "README.md",
    "content": "# UCTB (Urban Computing Tool Box)\n\n [![Python](https://img.shields.io/badge/python-3.6%7C3.7-blue)]() [![PyPI](https://img.shields.io/badge/pypi%20package-v0.3.5-sucess)](https://pypi.org/project/UCTB/) [![https://img.shields.io/badge/license-MIT-green](https://img.shields.io/badge/license-MIT-green)]() [![Documentation](https://img.shields.io/badge/api-reference-blue.svg)](https://uctb.github.io/UCTB)\n\n------\n\n**Urban Computing Tool Box** is a package providing [**ST paper list**](https://github.com/uctb/ST-Paper), [**urban datasets**](https://github.com/uctb/Urban-Dataset), [**spatial-temporal prediction models**](https://github.com/uctb/UCTB), and [**visualization tools**](https://github.com/uctb/visualization-tool-UCTB) for various urban computing tasks, such as traffic prediction, crowd flow prediction, ride-sharing demand prediction, etc. \n\nUCTB is a flexible and open package. You can use the data we provided or use your data, and the data structure is well stated in the [**document**](https://uctb.github.io/UCTB/md_file/urban_dataset.html#). \n\n## News\n\n**2024-03**: We have released two new datasets for **Metro** and **Bus** applications. These datasets provide hourly estimates of subway and bus ridership. [Welcome to explore them!](https://github.com/uctb/Urban-Dataset)\n\n**2023-06**: We have released a technical report entitled '*UCTB: An Urban Computing Tool Box for Spatiotemporal Crowd Flow Prediction*', introducing the design and implementation principles of UCTB. [[arXiv\\]](https://arxiv.org/abs/2306.04144)\n\n**2021-11**: Our paper on UCTB, entitled '*Exploring the Generalizability of Spatio-Temporal Traffic Prediction: Meta-Modeling and an Analytic Framework*', has been accepted by IEEE TKDE! [[IEEE Xplore](https://ieeexplore.ieee.org/document/9627543)] [[arXiv](https://arxiv.org/abs/2009.09379)]\n\n------\n\n## ST-Paper List\n\nWe maintain [a paper list](https://github.com/uctb/ST-Paper) focusing on spatio-temporal prediction papers from venues such as KDD, NeurIPS, AAAI, WWW, ICDE, IJCAI, WSDM, CIKM, and IEEE T-ITS. Note that the metadata may not encompass all relevant papers and could include unrelated ones, as selected by large language models.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/venue_stat.png\" alt=\".img\" style=\"zoom: 33%;height: 327px; width:424\" />\n\n## Urban Datasets\n\nUCTB releases [a public dataset repository](https://github.com/uctb/Urban-Dataset) including the following applications in 4 scenarios, with the detailed information provided in the table below. We are constantly working to release more datasets in the future.\n\n| **Application**  |        **City**        |       Time Span       | **Interval** |                           **Link**                           |\n| :--------------: | :--------------------: | :-------------------: | :----------: | :----------------------------------------------------------: |\n|   Bike-sharing   |          NYC           | 2013.07.01-2017.09.30 | 5 & 60 mins  | [5 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip)  [60 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/60_minutes/Bike_NYC.zip) |\n|   Bike-sharing   |        Chicago         | 2013.07.01-2017.09.30 | 5 & 60 mins  | [5 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip) [60 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/60_minutes/Bike_Chicago.zip) |\n|   Bike-sharing   |           DC           | 2013.07.01-2017.09.30 | 5 & 60 mins  | [5 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip) [60 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/60_minutes/Bike_DC.zip) |\n|       Bus        |          NYC           | 2022.02.01-2024.01.13 |   60 mins    | [60 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip) |\n|  Vehicle Speed   |           LA           | 2012.03.01-2012.06.28 |    5 mins    | [5 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip) |\n|  Vehicle Speed   |          BAY           | 2017.01.01-2017.07.01 |    5 mins    | [5 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip) |\n| Pedestrian Count |       Melbourne        | 2021.01.01-2022.11.01 |   60 mins    | [60 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.zip) |\n|   Ride-sharing   |  Chicago (community)   | 2013.01.01-2018.01.01 |   15 mins    | [15 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip) |\n|   Ride-sharing   | Chicago (census tract) | 2013.01.01-2018.01.01 |   15 mins    | [15 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip) |\n|   Ride-sharing   |          NYC           | 2009.01.01-2023.06.01 |    5 mins    | [5 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/5_minutes/Taxi_NYC.zip) |\n|      Metro       |          NYC           | 2022.02.01-2023.12.21 |   60 mins    | [60 mins](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip) |\n\nWe provide [detailed documents](https://github.com/uctb/Urban-Dataset/blob/main/Tutorial/tutorial.ipynb) about how to use these datasets.\n\n------\n\n## Prediction Models\n\nCurrently, the ST prediction model package supports the following models: (This toolbox is constructed based on some open-source repos. We appreciate these awesome implements. [See more details](https://uctb.github.io/UCTB/md_file/predictive_tool.html#)). \n\n|  Model  |   Data Format   |   Spatial Modeling Technique   |Graph Type|Temporal Modeling Technique|Temporal Knowledge|Module|\n| :--: | :--: | :--: |:--:|:--:|:--:|:--:|\n|   ARIMA   |   Both   |   N/A   |N/A|SARIMA|Closeness|``UCTB.model.ARIMA``|\n|   HM   |   Both   |   N/A   |N/A|N/A|Closeness|``UCTB.model.HM``|\n|   HMM   |   Both   |   N/A   |N/A|HMM|Closeness|``UCTB.model.HMM``|\n|   XGBoost   |   Both   |   N/A   |N/A|XGBoost|Closeness|``UCTB.model.XGBoost``|\n|   DeepST [[SIGSPATIAL 2016]](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf)  |   Grid   |   CNN   |N/A|CNN|Closeness, Period, Trend|``UCTB.model.DeepST``|\n|   ST-ResNet [[AAAI 2017]](https://arxiv.org/pdf/1610.00081.pdf)  |   Grid   |   CNN   |N/A|CNN|Closeness, Period, Trend|``UCTB.model.ST_ResNet``|\n|   DCRNN [[ICLR 2018]](https://arxiv.org/pdf/1707.01926.pdf) |   Node   |   GNN   |**Prior** (Sensor Network)|RNN|Closeness|``UCTB.model.DCRNN``|\n|   GeoMAN [[IJCAI 2018]](https://www.ijcai.org/proceedings/2018/0476.pdf) |   Node   |   Attention   |**Prior** (Sensor Networks)|Attention+LSTM|Closeness|``UCTB.model.GeoMAN``|\n|   STGCN [[IJCAI 2018]](https://www.ijcai.org/proceedings/2018/0505.pdf) |   Node   |   GNN   |**Prior** (Traffic Network)|Gated CNN|Closeness|``UCTB.model.STGCN``|\n|   GraphWaveNet [[IJCAI 2019]](https://www.ijcai.org/proceedings/2019/0264.pdf)  |   Node   |   GNN   |**Prior** (Sensor Network) + **Adaptive**|TCN|Closeness|``UCTB.model.GraphWaveNet``|\n|   ASTGCN [[AAAI 2019]](https://ojs.aaai.org/index.php/AAAI/article/view/3881) |   Node   |   GNN+Attention   |**Prior** (Traffic Network)|Attention|Closeness, Period, Trend|``UCTB.model.ASTGCN``|\n|  ST-MGCN [[AAAI 2019]](https://ojs.aaai.org/index.php/AAAI/article/view/4247) |   Node   |   GNN   |**Prior** (Neighborhood, Functional similarity, Transportation connectivity)|CGRNN|Closeness|``UCTB.model.ST_MGCN``|\n|   GMAN [[AAAI 2020]](https://ojs.aaai.org/index.php/AAAI/article/view/5477/5333) |   Node   |   Attention   |**Prior** (Road Network)|Attention|Closeness|``UCTB.model.GMAN``|\n|   STSGCN [[AAAI 2020]](https://ojs.aaai.org/index.php/AAAI/article/view/5438) |   Node   |   GNN+Attention   |**Prior** (Spatial Network)|Attention|Closeness|``UCTB.model.STSGCN``|\n|  AGCRN [[NeurIPS 2020]](https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf) |   Node   |   GNN   |**Adaptive**|RNN|Closeness|``UCTB.model.AGCRN``|\n|  MTGNN [[KDD 2020]](https://dl.acm.org/doi/abs/10.1145/3394486.3403118) |   Node   |   GNN   |**Adaptive**|TCN|Closeness|``UCTB.model.MTGNN``|\n|   STMeta [[TKDE 2021]](https://arxiv.org/abs/2009.09379)  |   Node   |   GNN   |**Prior** (Proximity, Functionality, Interaction/Same-line)|LSTM/RNN|Closeness, Period, Trend|``UCTB.model.STMeta``|\n\n------\n\n## Visualization Tool\n\nThe Visualization tool integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_5.png\" alt=\".img\" style=\"zoom: 33%;\" />\n\nWelcome to visit the [website](http://39.107.116.221/) for a trial! \n\n## Installation\n\nUCTB toolbox may not work successfully with the upgrade of some packages. We thus encourage you to use the specific version of packages to avoid unseen errors. ***To avoid potential conflict, we highly recommend you install UCTB vis Anaconda.*** The installation details are in our [documents](https://uctb.github.io/UCTB/md_file/installation.html). \n\n## Citation\n\nIf UCTB is helpful for your work, please cite and star our project.\n\n```\n@article{uctb_2023,\n  title={UCTB: An Urban Computing Tool Box for Spatiotemporal Crowd Flow Prediction},\n  author={Chen, Liyue and Chai, Di and Wang, Leye},\n  journal={arXiv preprint arXiv:2306.04144},\n  year={2023}}\n\n@article{STMeta,\n  author={Wang, Leye and Chai, Di and Liu, Xuanzhe and Chen, Liyue and Chen, Kai},\n  journal={IEEE Transactions on Knowledge and Data Engineering}, \n  title={Exploring the Generalizability of Spatio-Temporal Traffic Prediction: Meta-Modeling and an Analytic Framework}, \n  year={2023},\n  volume={35},\n  number={4},\n  pages={3870-3884},\n  doi={10.1109/TKDE.2021.3130762}}\n```\n"
  },
  {
    "path": "UCTB/__init__.py",
    "content": "\r\nfrom . import dataset\r\n\r\nfrom . import evaluation\r\nfrom . import model\r\nfrom . import model_unit\r\n\r\nfrom . import train\r\nfrom . import preprocess\r\n\r\nfrom . import utils\r\n\r\n__version__ = '0.3.0'"
  },
  {
    "path": "UCTB/dataset/__init__.py",
    "content": "from .data_loader import NodeTrafficLoader, TransferDataLoader, GridTrafficLoader\r\nfrom .dataset import DataSet"
  },
  {
    "path": "UCTB/dataset/context_loader.py",
    "content": "from abc import ABC, abstractmethod\n\nclass TemporalContextLoader(ABC):\n\n    def __init__(self, traffic_dataloader):\n\n        self.weather_data = self.get_weather()\n        self.holiday_data = self.get_holiday()\n        self.weather_data = self.get_temporal_position()\n        pass\n\n    @abstractmethod\n    def get_weather(self, arg):\n        '''\n        Input:\n            default weather features shape: (T, D_t)\n            detailed weather features shape: (T, N, D_t)\n            station info [[lat1, lng1], ....]\n\n        Function to be implemented:\n            Func 1 (T, ?, D_t) -> bind/replicate (optional) -> (T, N, D_t)\n            Func 2 move Context sample\n        '''\n        # # func 1 推断天气\n        # self.infer_weather()\n\n        # func 2 构造历史context样本\n        # # move Context sample\n        # self.train_ef_closeness = None\n        # self.train_ef_period = None\n        # self.train_ef_trend = None\n        # self.train_lstm_ef =  None\n        # self.test_ef_closeness = None\n        # self.test_ef_period = None\n        # self.test_ef_trend = None\n        # self.test_lstm_ef = None\n        # if len(external_feature) > 0:\n        #     self.external_move_sample = ST_MoveSample(closeness_len=self.closeness_len,\n        #                                     period_len=self.period_len,\n        #                                     trend_len=self.trend_len, target_length=0, daily_slots=self.daily_slots)\n\n        #     self.train_ef_closeness, self.train_ef_period, self.train_ef_trend, _ = self.external_move_sample.move_sample(self.train_ef)\n\n        #     self.test_ef_closeness, self.test_ef_period, self.test_ef_trend, _ = self.external_move_sample.move_sample(self.test_ef)\n\n\n        #     if self.external_lstm_len is not None and self.external_lstm_len > 0:    \n        #         self.external_move_sample = ST_MoveSample(closeness_len=self.external_lstm_len,period_len=0,trend_len=0, target_length=0, daily_slots=self.daily_slots)\n\n        #         self.train_lstm_ef, _, _, _ = self.external_move_sample.move_sample(self.train_ef)\n\n        #         self.test_lstm_ef, _, _, _ = self.external_move_sample.move_sample(self.test_ef)\n\n        #     self.train_ef = self.train_ef[-self.train_sequence_len - target_length: -target_length]\n        #     self.test_ef = self.test_ef[-self.test_sequence_len - target_length: -target_length]\n            \n        #     # weather\n        #     self.train_lstm_ef = self.train_lstm_ef[-self.train_sequence_len - target_length: -target_length]\n        #     self.test_lstm_ef = self.test_lstm_ef[-self.test_sequence_len - target_length: -target_length]\n            \n        # pass\n\n    # @abstractmethod\n    # def infer_weather(sellf, arg):\n    #     pass\n    \n    @abstractmethod\n    def get_holiday(sellf, arg):\n        '''\n        Input:\n            parser function or csv file\n\n        Function to be implemented:\n            Func 1 (T//daily_slots, 1) -> temporal replicate ->  (T, 1)\n        '''\n        # parse by api\n\n        # load by file\n        pass\n    \n    # @staticmethod\n    @abstractmethod\n    def get_temporal_position(self, arg):\n        ...\n\n\n\nclass SpatialContextLoader(ABC):\n     \n    def __init__(self, traffic_dataloader):\n        self.poi = self.get_poi()\n        \n    @abstractmethod\n    def get_poi(sellf, arg):\n        '''\n        Input:\n            parser function or csv file\n\n        Function to be implemented:\n            Func 1 (?, N, D_s) -> temporal replicate -> (T, N, D_s)\n        '''\n\n        # load by file\n        pass"
  },
  {
    "path": "UCTB/dataset/data_loader.py",
    "content": "import os\nimport copy\nimport datetime\nimport numpy as np\nfrom dateutil.parser import parse\nfrom sklearn.metrics.pairwise import cosine_similarity\nfrom scipy.stats import pearsonr\nfrom ..preprocess.time_utils import is_work_day_china, is_work_day_america, is_valid_date\nfrom ..preprocess import MoveSample, SplitData, ST_MoveSample, chooseNormalizer\nfrom .dataset import DataSet\nfrom ..preprocess.preprocessor import *\n\nclass GridTrafficLoader(object):\n\n    def __init__(self,\n                 dataset,\n                 city=None,\n                 data_range='all',\n                 train_data_length='all',\n                 test_ratio=0.1,\n                 closeness_len=6,\n                 period_len=7,\n                 trend_len=4,\n                 target_length=1,\n                 normalize=True,\n                 workday_parser=is_work_day_america,\n                 data_dir=None,\n                 MergeIndex=1,\n                 MergeWay=\"sum\",**kwargs):\n                 \n        self.dataset = DataSet(dataset, MergeIndex, MergeWay, city,data_dir=data_dir)\n\n        self.loader_id = \"{}_{}_{}_{}_{}_{}_{}_G\".format(data_range, train_data_length, test_ratio, closeness_len, period_len, trend_len, self.dataset.time_fitness)\n\n        self.daily_slots = 24 * 60 / self.dataset.time_fitness\n\n        if type(data_range) is str and data_range.lower() == 'all':\n            data_range = [0, len(self.dataset.grid_traffic)]\n        elif type(data_range) is float:\n            data_range = [0, int(data_range * len(self.dataset.grid_traffic))]\n        else:\n            data_range = [int(data_range[0] * self.daily_slots), int(data_range[1] * self.daily_slots)]\n\n        num_time_slots = data_range[1] - data_range[0]\n        self.traffic_data = self.dataset.grid_traffic[data_range[0]:data_range[1], :].astype(np.float32)\n\n        # external feature\n        external_feature = []\n        # weather\n        if len(self.dataset.external_feature_weather) > 0:\n            external_feature.append(self.dataset.external_feature_weather[data_range[0]:data_range[1]])\n            # Weekday Feature\n            weekday_feature = [[1 if workday_parser(parse(self.dataset.time_range[0])\n                                                    + datetime.timedelta(hours=e * self.dataset.time_fitness / 60), self.dataset.city) else 0] \\\n                            for e in range(data_range[0], num_time_slots + data_range[0])]\n            # Hour Feature\n            hour_feature = [[(parse(self.dataset.time_range[0]) +\n                            datetime.timedelta(hours=e * self.dataset.time_fitness / 60)).hour / 24.0]\n                            for e in range(data_range[0], num_time_slots + data_range[0])]\n\n            external_feature.append(weekday_feature)\n            external_feature.append(hour_feature)\n            external_feature = np.concatenate(external_feature, axis=-1).astype(np.float32)\n            self.external_dim = external_feature.shape[1]\n        else:\n            self.external_dim = len(external_feature)\n\n        self.height, self.width = self.traffic_data.shape[1], self.traffic_data.shape[2]\n\n        if test_ratio > 1 or test_ratio < 0:\n            raise ValueError('test_ratio ')\n        train_test_ratio = [1 - test_ratio, test_ratio]\n\n        self.train_data, self.test_data = SplitData.split_data(self.traffic_data, train_test_ratio)\n        self.train_ef, self.test_ef = SplitData.split_data(external_feature, train_test_ratio)\n\n        # Normalize the traffic data\n        if normalize:\n            self.normalizer = chooseNormalizer(normalize,self.train_data)\n            self.train_data = self.normalizer.transform(self.train_data)\n            self.test_data = self.normalizer.transform(self.test_data)\n\n        if train_data_length.lower() != 'all':\n            train_day_length = int(train_data_length)\n            self.train_data = self.train_data[-int(train_day_length * self.daily_slots):]\n            self.train_ef = self.train_ef[-int(train_day_length * self.daily_slots):]\n\n        # expand the test data\n        expand_start_index = len(self.train_data) - max(int(self.daily_slots * period_len),\n                                                        int(self.daily_slots * 7 * trend_len), closeness_len)\n\n        self.test_data = np.vstack([self.train_data[expand_start_index:], self.test_data])\n        self.test_ef = np.vstack([self.train_ef[expand_start_index:], self.test_ef])\n\n        assert type(closeness_len) is int and closeness_len >= 0\n        assert type(period_len) is int and period_len >= 0\n        assert type(trend_len) is int and trend_len >= 0\n\n        self.closeness_len = closeness_len\n        self.period_len = period_len\n        self.trend_len = trend_len\n\n        # init move sample obj\n        self.st_move_sample = ST_MoveSample(closeness_len=closeness_len,\n                                            period_len=period_len,\n                                            trend_len=trend_len, target_length=target_length, daily_slots=self.daily_slots)\n\n        self.train_closeness, \\\n        self.train_period, \\\n        self.train_trend, \\\n        self.train_y = self.st_move_sample.move_sample(self.train_data)\n\n        self.test_closeness, \\\n        self.test_period, \\\n        self.test_trend, \\\n        self.test_y = self.st_move_sample.move_sample(self.test_data)\n\n        self.train_closeness = self.train_closeness.squeeze(-1)\n        self.train_period = self.train_period.squeeze(-1)\n        self.train_trend = self.train_trend.squeeze(-1)\n\n        self.test_closeness = self.test_closeness.squeeze(-1)\n        self.test_period = self.test_period.squeeze(-1)\n        self.test_trend = self.test_trend.squeeze(-1)\n\n        self.train_sequence_len = max((len(self.train_closeness), len(self.train_period), len(self.train_trend)))\n        self.test_sequence_len = max((len(self.test_closeness), len(self.test_period), len(self.test_trend)))\n\n        # external feature\n        self.train_ef = self.train_ef[-self.train_sequence_len - target_length: -target_length]\n        self.test_ef = self.test_ef[-self.test_sequence_len - target_length: -target_length]\n\n\nclass NodeTrafficLoader(object):\n    \"\"\"The data loader that extracts and processes data from a :obj:`DataSet` object.\n\n    Args:\n        dataset (str): A string containing path of the dataset pickle file or a string of name of the dataset.\n        city (:obj:`str` or ``None``): ``None`` if dataset is file path, or a string of name of the city.\n            Default: ``None``\n        data_range: The range of data extracted from ``self.dataset`` to be further used. If set to ``'all'``, all data in\n            ``self.dataset`` will be used. If set to a float between 0.0 and 1.0, the relative former proportion of data in\n            ``self.dataset`` will be used. If set to a list of two integers ``[start, end]``, the data from *start* day to\n            (*end* - 1) day of data in ``self.dataset`` will be used. Default: ``'all'``\n        train_data_length: The length of train data. If set to ``'all'``, all data in the split train set will be used.\n            If set to int, the latest ``train_data_length`` days of data will be used as train set. Default: ``'all'``\n        test_ratio (float): The ratio of test set as data will be split into train set and test set. Default: 0.1\n        closeness_len (int): The length of closeness data history. The former consecutive ``closeness_len`` time slots\n            of data will be used as closeness history. Default: 6\n        period_len (int): The length of period data history. The data of exact same time slots in former consecutive\n            ``period_len`` days will be used as period history. Default: 7\n        trend_len (int): The length of trend data history. The data of exact same time slots in former consecutive\n            ``trend_len`` weeks (every seven days) will be used as trend history. Default: 4\n        target_length (int): The numbers of steps that need prediction by one piece of history data. Have to be 1 now.\n            Default: 1\n        normalize (bool|str|object): Select which normalizer to normalize input data. Default: ``True``\n        workday_parser: Used to build external features to be used in neural methods. Default: ``is_work_day_america``\n        with_tpe (bool): If ``True``, data loader will build time position embeddings. Default: ``False``\n        data_dir (:obj:`str` or ``None``): The dataset directory. If set to ``None``, a directory will be created. If\n            ``dataset`` is file path, ``data_dir`` should be ``None`` too. Default: ``None``\n        MergeIndex(int): The granularity of dataset will be ``MergeIndex`` * original granularity.\n        MergeWay(str): How to change the data granularity. Now it can be ``sum`` ``average`` or ``max``.\n        remove(bool): If ``True``, dataloader  will remove stations whose average traffic is less than 1. \n            Othewise, dataloader will use all stations.\n\n    Attributes:\n        dataset (DataSet): The DataSet object storing basic data.\n        daily_slots (int): The number of time slots in one single day.\n        station_number (int): The number of nodes.\n        external_dim (int): The number of dimensions of external features.\n        train_closeness (np.ndarray): The closeness history of train set data. When ``with_tpe`` is ``False``,\n            its shape is [train_time_slot_num, ``station_number``, ``closeness_len``, 1].\n            On the dimension of ``closeness_len``, data are arranged from earlier time slots to later time slots.\n            If ``closeness_len`` is set to 0, train_closeness will be an empty ndarray.\n            ``train_period``, ``train_trend``, ``test_closeness``, ``test_period``, ``test_trend`` have similar shape\n            and construction.\n        train_y (np.ndarray): The train set data. Its shape is [train_time_slot_num, ``station_number``, 1].\n            ``test_y`` has similar shape and construction.\n    \"\"\"\n\n    def __init__(self,\n                 dataset,\n                 city=None,\n                 data_range='all',\n                 train_data_length='all',\n                 test_ratio=0.1,\n                 closeness_len=6,\n                 period_len=7,\n                 trend_len=4,\n                 target_length=1,\n                 normalize=True,\n                 workday_parser=is_work_day_america,\n                 with_tpe=False,\n                 data_dir=None,\n                 MergeIndex=1,\n                 MergeWay=\"sum\",\n                 remove=True,**kwargs):\n\n        self.dataset = DataSet(dataset, MergeIndex, MergeWay, city,data_dir=data_dir)\n\n        self.loader_id = \"{}_{}_{}_{}_{}_{}_{}_N\".format(data_range, train_data_length, test_ratio, closeness_len, period_len, trend_len, self.dataset.time_fitness)\n        \n        self.daily_slots = int(24 * 60 / self.dataset.time_fitness)\n\n        self.closeness_len = int(closeness_len)\n        self.period_len = int(period_len)\n        self.trend_len = int(trend_len)\n\n        assert type(self.closeness_len) is int and self.closeness_len >= 0\n        assert type(self.period_len) is int and self.period_len >= 0\n        assert type(self.trend_len) is int and self.trend_len >= 0\n\n        if type(data_range) is str and data_range.lower().startswith(\"0.\"):\n            data_range = float(data_range)\n        if type(data_range) is str and data_range.lower() == 'all':\n            data_range = [0, len(self.dataset.node_traffic)]\n        elif type(data_range) is float:\n            data_range = [0, int(data_range * len(self.dataset.node_traffic))]\n        else:\n            data_range = [int(data_range[0] * self.daily_slots), int(data_range[1] * self.daily_slots)]\n\n        num_time_slots = data_range[1] - data_range[0]\n\n        # traffic feature\n        \n\n        self.traffic_data = self.dataset.node_traffic[data_range[0]:data_range[1], :].astype(\n             np.float32)\n\n        # external feature\n        external_feature = []\n        # weather\n        if len(self.dataset.external_feature_weather) > 0:\n            external_feature.append(self.dataset.external_feature_weather[data_range[0]:data_range[1]])\n            # Weekday Feature\n            weekday_feature = [[1 if workday_parser(parse(self.dataset.time_range[0])\n                                                    + datetime.timedelta(hours=e * self.dataset.time_fitness / 60), self.dataset.city) else 0] \\\n                            for e in range(data_range[0], num_time_slots + data_range[0])]\n            # Hour Feature\n            hour_feature = [[(parse(self.dataset.time_range[0]) +\n                            datetime.timedelta(hours=e * self.dataset.time_fitness / 60)).hour / 24.0]\n                            for e in range(data_range[0], num_time_slots + data_range[0])]\n\n            external_feature.append(weekday_feature)\n            external_feature.append(hour_feature)\n            external_feature = np.concatenate(external_feature, axis=-1).astype(np.float32)\n            self.external_dim = external_feature.shape[1]\n        else:\n            self.external_dim = len(external_feature)\n        \n        \n        if test_ratio > 1 or test_ratio < 0:\n            raise ValueError('test_ratio ')\n        self.train_test_ratio = [1 - test_ratio, test_ratio]\n\n        self.train_data, self.test_data = SplitData.split_data(self.traffic_data, self.train_test_ratio)\n        if remove:\n            self.traffic_data_index = np.where(np.mean(self.train_data, axis=0) * self.daily_slots > 1)[0]\n        else:\n            self.traffic_data_index = np.arange(self.dataset.node_traffic.shape[1])\n\n        self.traffic_data = self.traffic_data[:, self.traffic_data_index]\n        self.train_data = self.train_data[:, self.traffic_data_index]\n        self.test_data = self.test_data[:, self.traffic_data_index]\n        self.station_number = self.traffic_data.shape[1]\n        \n        self.train_ef, self.test_ef = SplitData.split_data(external_feature, self.train_test_ratio)\n\n        # Normalize the traffic data\n\n        self.normalizer = chooseNormalizer(normalize,self.train_data)\n        self.train_data = self.normalizer.transform(self.train_data)\n        self.test_data = self.normalizer.transform(self.test_data)\n\n        if train_data_length.lower() != 'all':\n            train_day_length = int(train_data_length)\n            self.train_data = self.train_data[-int(train_day_length * self.daily_slots):]\n            self.train_ef = self.train_ef[-int(train_day_length * self.daily_slots):]\n\n        # expand the test data\n        expand_start_index = len(self.train_data) - \\\n                             max(int(self.daily_slots * self.period_len),\n                                 int(self.daily_slots * 7 * self.trend_len),\n                                 self.closeness_len)\n\n        self.test_data = np.vstack([self.train_data[expand_start_index:], self.test_data])\n        self.test_ef = np.vstack([self.train_ef[expand_start_index:], self.test_ef])\n\n        # init move sample obj\n        self.st_move_sample = ST_MoveSample(closeness_len=self.closeness_len,\n                                            period_len=self.period_len,\n                                            trend_len=self.trend_len, target_length=target_length, daily_slots=self.daily_slots)\n\n        self.train_closeness, \\\n        self.train_period, \\\n        self.train_trend, \\\n        self.train_y = self.st_move_sample.move_sample(self.train_data)\n\n        self.test_closeness, \\\n        self.test_period, \\\n        self.test_trend, \\\n        self.test_y = self.st_move_sample.move_sample(self.test_data)\n\n        self.train_sequence_len = max((len(self.train_closeness), len(self.train_period), len(self.train_trend)))\n        self.test_sequence_len = max((len(self.test_closeness), len(self.test_period), len(self.test_trend)))\n\n        # external feature\n        self.train_ef = self.train_ef[-self.train_sequence_len - target_length: -target_length]\n        self.test_ef = self.test_ef[-self.test_sequence_len - target_length: -target_length]\n\n        if with_tpe:\n\n            # Time position embedding\n            self.closeness_tpe = np.array(range(1, self.closeness_len + 1), dtype=np.float32)\n            self.period_tpe = np.array(range(1 * int(self.daily_slots),\n                                             self.period_len * int(self.daily_slots) + 1,\n                                             int(self.daily_slots)), dtype=np.float32)\n            self.trend_tpe = np.array(range(1 * int(self.daily_slots) * 7,\n                                            self.trend_len * int(self.daily_slots) * 7 + 1,\n                                            int(self.daily_slots) * 7), dtype=np.float32)\n\n            self.train_closeness_tpe = np.tile(np.reshape(self.closeness_tpe, [1, 1, -1, 1]),\n                                               [len(self.train_closeness), len(self.traffic_data_index), 1, 1])\n            self.train_period_tpe = np.tile(np.reshape(self.period_tpe, [1, 1, -1, 1]),\n                                            [len(self.train_period), len(self.traffic_data_index), 1, 1])\n            self.train_trend_tpe = np.tile(np.reshape(self.trend_tpe, [1, 1, -1, 1]),\n                                           [len(self.train_trend), len(self.traffic_data_index), 1, 1])\n\n            self.test_closeness_tpe = np.tile(np.reshape(self.closeness_tpe, [1, 1, -1, 1]),\n                                              [len(self.test_closeness), len(self.traffic_data_index), 1, 1])\n            self.test_period_tpe = np.tile(np.reshape(self.period_tpe, [1, 1, -1, 1]),\n                                           [len(self.test_period), len(self.traffic_data_index), 1, 1])\n            self.test_trend_tpe = np.tile(np.reshape(self.trend_tpe, [1, 1, -1, 1]),\n                                          [len(self.test_trend), len(self.traffic_data_index), 1, 1])\n\n            self.tpe_dim = self.train_closeness_tpe.shape[-1]\n\n            # concat temporal feature with time position embedding\n            self.train_closeness = np.concatenate((self.train_closeness, self.train_closeness_tpe,), axis=-1)\n            self.train_period = np.concatenate((self.train_period, self.train_period_tpe,), axis=-1)\n            self.train_trend = np.concatenate((self.train_trend, self.train_trend_tpe,), axis=-1)\n\n            self.test_closeness = np.concatenate((self.test_closeness, self.test_closeness_tpe,), axis=-1)\n            self.test_period = np.concatenate((self.test_period, self.test_period_tpe,), axis=-1)\n            self.test_trend = np.concatenate((self.test_trend, self.test_trend_tpe,), axis=-1)\n\n        else:\n\n            self.tpe_dim = None\n\n\n    def st_map(self, zoom=11, style='mapbox://styles/rmetfc/ck1manozn0edb1dpmvtzle2cp', build_order=None):\n        if self.dataset.node_station_info is None or len(self.dataset.node_station_info) == 0:\n            raise ValueError('No station information found in dataset')\n\n        import numpy as np\n        import plotly\n        from plotly.graph_objs import Scattermapbox, Layout\n\n        mapboxAccessToken = \"pk.eyJ1Ijoicm1ldGZjIiwiYSI6ImNrMW02YmwxbjAxN24zam9kNGVtMm5raWIifQ.FXKqZCxsFK-dGLLNdeRJHw\"\n\n        # os.environ['MAPBOX_API_KEY'] = mapboxAccessToken\n\n        # lat_lng_name_list = [e[2:] for e in self.dataset.node_station_info]\n        build_order = build_order or list(range(len(self.dataset.node_station_info)))\n\n        color = ['rgb(255, 0, 0)' for _ in build_order]\n\n        lat = np.array([float(e[2]) for e in self.dataset.node_station_info])[self.traffic_data_index]\n        lng = np.array([float(e[3]) for e in self.dataset.node_station_info])[self.traffic_data_index]\n        text = [str(e) for e in range(len(build_order))]\n        if self.dataset.city:\n            file_name = self.dataset.dataset + '-' + self.dataset.city + '.html'\n        else:\n            file_name = self.dataset.dataset+'.html'\n        bikeStations = [Scattermapbox(\n            lon=lng,\n            lat=lat,\n            text=text,\n            mode='markers',\n            marker=dict(\n                size=6,\n                #  color=['rgb(%s, %s, %s)' % (255,\n                #                                               195 - e * 195 / max(build_order),\n                #                                               195 - e * 195 / max(build_order)) for e in build_order],\n                color=color,\n                opacity=1,\n            ))]\n\n        layout = Layout(\n            title='Bike Station Location & The latest built stations with deeper color',\n            autosize=True,\n            hovermode='closest',\n            showlegend=False,\n            mapbox=dict(\n                accesstoken=mapboxAccessToken,\n                bearing=0,\n                center=dict(\n                    lat=np.median(lat),\n                    lon=np.median(lng)\n                ),\n                pitch=0,\n                zoom=zoom,\n                style=style\n            ),\n        )\n\n        fig = dict(data=bikeStations, layout=layout)\n        plotly.offline.plot(fig, filename=file_name)\n\n    def make_concat(self, node='all', is_train=True):\n        \"\"\"A function to concatenate all closeness, period and trend history data to use as inputs of models.\n\n        Args:\n            node (int or ``'all'``): To specify the index of certain node. If set to ``'all'``, return the concatenation\n                result of all nodes. If set to an integer, it will be the index of the selected node. Default: ``'all'``\n            is_train (bool): If set to ``True``, ``train_closeness``, ``train_period``, and ``train_trend`` will be\n                concatenated. If set to ``False``, ``test_closeness``, ``test_period``, and ``test_trend`` will be\n                concatenated. Default: True\n\n        Returns:\n            np.ndarray: Function returns an ndarray with shape as\n            [time_slot_num, ``station_number``, ``closeness_len`` + ``period_len`` + ``trend_len``, 1],\n            and time_slot_num is the temporal length of train set data if ``is_train`` is ``True``\n            or the temporal length of test set data if ``is_train`` is ``False``.\n            On the second dimension, data are arranged as\n            ``earlier closeness -> later closeness -> earlier period -> later period -> earlier trend -> later trend``.\n        \"\"\"\n\n        if is_train:\n            length = len(self.train_y)\n            closeness = self.train_closeness\n            period = self.train_period\n            trend = self.train_trend\n        else:\n            length = len(self.test_y)\n            closeness = self.test_closeness\n            period = self.test_period\n            trend = self.test_trend\n        if node == 'all':\n            node = list(range(self.station_number))\n        else:\n            node = [node]\n        history = np.zeros([length, len(node), self.closeness_len + self.period_len + self.trend_len])\n        for i in range(len(node)):\n            for c in range(self.closeness_len):\n                history[:, i, c] = closeness[:, node[i], c, -1]\n            for p in range(self.period_len):\n                history[:, i, self.closeness_len + p] = period[:, node[i], p, -1]\n            for t in range(self.trend_len):\n                history[:, i, self.closeness_len + self.period_len + t] = trend[:, node[i], t, -1]\n        history = np.expand_dims(history, 3)\n        return history\n\n\nclass TransferDataLoader(object):\n\n    def __init__(self, sd_params, td_params, model_params, td_data_length=None):\n\n        if td_data_length:\n            td_params.update({'train_data_length': td_data_length})\n\n        self.sd_loader = NodeTrafficLoader(**sd_params, **model_params)\n        self.td_loader = NodeTrafficLoader(**td_params, **model_params)\n\n        td_params.update({'train_data_length': '180'})\n        self.fake_td_loader = NodeTrafficLoader(**td_params, **model_params)\n\n    def traffic_sim(self):\n\n        assert self.sd_loader.daily_slots == self.td_loader.daily_slots\n\n        similar_record = []\n\n        for i in range(0, self.sd_loader.train_data.shape[0] - self.td_loader.train_data.shape[0],\n                       int(self.sd_loader.daily_slots)):\n\n            sim = cosine_similarity(self.td_loader.train_data.transpose(),\n                                    self.sd_loader.train_data[i:i + self.td_loader.train_data.shape[0]].transpose())\n\n            max_sim, max_index = np.max(sim, axis=1), np.argmax(sim, axis=1)\n\n            if len(similar_record) == 0:\n                similar_record = [[max_sim[e], max_index[e], i, i + self.td_loader.train_data.shape[0]]\n                                  for e in range(len(max_sim))]\n            else:\n                for index in range(len(similar_record)):\n                    if similar_record[index][0] < max_sim[index]:\n                        similar_record[index] = [max_sim[index], max_index[index], i,\n                                                 i + self.td_loader.train_data.shape[0]]\n\n        return similar_record\n\n    def traffic_sim_fake(self):\n\n        assert self.sd_loader.daily_slots == self.fake_td_loader.daily_slots\n\n        similar_record = []\n\n        for i in range(0, self.sd_loader.train_data.shape[0] - self.fake_td_loader.train_data.shape[0],\n                       int(self.sd_loader.daily_slots)):\n\n            sim = cosine_similarity(self.fake_td_loader.train_data.transpose(),\n                                    self.sd_loader.train_data[\n                                    i:i + self.fake_td_loader.train_data.shape[0]].transpose())\n\n            max_sim, max_index = np.max(sim, axis=1), np.argmax(sim, axis=1)\n\n            if len(similar_record) == 0:\n                similar_record = [[max_sim[e], max_index[e], i, i + self.fake_td_loader.train_data.shape[0]]\n                                  for e in range(len(max_sim))]\n            else:\n                for index in range(len(similar_record)):\n                    if similar_record[index][0] < max_sim[index]:\n                        similar_record[index] = [max_sim[index], max_index[index], i,\n                                                 i + self.td_loader.train_data.shape[0]]\n\n        return similar_record\n\n    def checkin_sim(self):\n\n        from sklearn.metrics.pairwise import cosine_similarity\n\n        td_checkin = np.array([e[0] for e in self.td_loader.dataset.data['ExternalFeature']['CheckInFeature']]\n                              )[self.td_loader.traffic_data_index]\n        sd_checkin = np.array([e[0] for e in self.sd_loader.dataset.data['ExternalFeature']['CheckInFeature']]\n                              )[self.sd_loader.traffic_data_index]\n\n        td_checkin = td_checkin / (np.max(td_checkin, axis=1, keepdims=True) + 0.0001)\n        sd_checkin = sd_checkin / (np.max(sd_checkin, axis=1, keepdims=True) + 0.0001)\n\n        # cs = cosine_similarity(td_checkin, sd_checkin)\n\n        # similar_record = [[e[np.argmax(e)], np.argmax(e), ] for e in cs]\n\n        similar_record = []\n        for td_index in range(len(td_checkin)):\n            tmp_sim_record = []\n            for sd_index in range(len(sd_checkin)):\n                r, p = pearsonr(td_checkin[td_index], sd_checkin[sd_index])\n                tmp_sim_record.append([r, sd_index,\n                                       len(self.sd_loader.train_y) - len(self.td_loader.train_y),\n                                       len(self.sd_loader.train_y)])\n            similar_record.append(max(tmp_sim_record, key=lambda x: x[0]))\n\n        return similar_record\n\n    def checkin_sim_sd(self):\n\n        sd_checkin = np.array([e[0] for e in self.sd_loader.dataset.data['ExternalFeature']['CheckInFeature']]\n                              )[self.sd_loader.traffic_data_index]\n        sd_checkin = sd_checkin / (np.max(sd_checkin, axis=1, keepdims=True) + 0.0001)\n\n        cs = cosine_similarity(sd_checkin, sd_checkin) - np.eye(sd_checkin.shape[0])\n\n        return np.array([np.argmax(e) for e in cs], np.int32)\n\n    def poi_sim(self):\n\n        from sklearn.metrics.pairwise import cosine_similarity\n\n        td_checkin = np.array([e[1] for e in self.td_loader.dataset.data['ExternalFeature']['CheckInFeature']]\n                              )[self.td_loader.traffic_data_index]\n        sd_checkin = np.array([e[1] for e in self.sd_loader.dataset.data['ExternalFeature']['CheckInFeature']]\n                              )[self.sd_loader.traffic_data_index]\n\n        return [[e[np.argmax(e)], np.argmax(e), ] for e in cosine_similarity(td_checkin, sd_checkin)]\n\n"
  },
  {
    "path": "UCTB/dataset/dataset.py",
    "content": "import os\r\nimport wget\r\nimport pickle\r\nimport tarfile\r\nimport numpy as np\r\n\r\n\r\nclass DataSet(object):\r\n    \"\"\"An object storing basic data from a formatted pickle file.\r\n    See also `Build your own datasets <./md_file/tutorial.html>`_.\r\n    Args:\r\n        dataset (str): A string containing path of the dataset pickle file or a string of name of the dataset.\r\n        city (str or ``None``): ``None`` if dataset is file path, or a string of name of the city. Default: ``None``\r\n        data_dir (str or ``None``): The dataset directory. If set to ``None``, a directory will be created.\r\n            If ``dataset`` is file path, ``data_dir`` should be ``None`` too. Default: ``None``\r\n    Attributes:\r\n        data (dict): The data directly from the pickle file. ``data`` may have a ``data['contribute_data']`` dict to\r\n            store supplementary data.\r\n        time_range (list): From ``data['TimeRange']`` in the format of [YYYY-MM-DD, YYYY-MM-DD] indicating the time\r\n            range of the data.\r\n        time_fitness (int): From ``data['TimeFitness']`` indicating how many minutes is a single time slot.\r\n        node_traffic (np.ndarray): Data recording the main stream data of the nodes in during the time range.\r\n            From ``data['Node']['TrafficNode']`` with shape as [time_slot_num, node_num].\r\n        node_monthly_interaction (np.ndarray): Data recording the monthly interaction of pairs of nodes.\r\n            Its shape is [month_num, node_num, node_num].It's from ``data['Node']['TrafficMonthlyInteraction']``\r\n            and is used to build interaction graph.\r\n            Its an optional attribute and can be set as an empty list if interaction graph is not needed.\r\n        node_station_info (dict): A dict storing the coordinates of nodes. It shall be formatted as {id (may be\r\n            arbitrary): [id (when sorted, should be consistant with index of ``node_traffic``), latitude, longitude,\r\n            other notes]}. It's from ``data['Node']['StationInfo']`` and is used to build distance graph.\r\n            Its an optional attribute and can be set as an empty list if distance graph is not needed.\r\n        MergeIndex(int): A int number that used to adjust the granularity of the dataset, the granularity of the new\r\n            dataset is time_fitness*MergeIndex. default: 1\r\n        MergeWay(str):can be `sum` and `average`.  default: ``sum\r\n    \"\"\"\r\n\r\n    def __init__(self, dataset, MergeIndex, MergeWay, city=None, data_dir=None):\r\n        self.dataset = dataset\r\n        self.city = city\r\n        self.MergeIndex = int(MergeIndex)\r\n        self.MergeWay = MergeWay.lower()\r\n\r\n        if data_dir is None:\r\n            data_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'data')\r\n\r\n        if os.path.isdir(data_dir) is False:\r\n            os.makedirs(data_dir)\r\n\r\n        if self.city is not None:\r\n            pkl_file_name = os.path.join(data_dir, '{}_{}.pkl'.format(self.dataset, self.city))\r\n        else:\r\n            pkl_file_name = self.dataset\r\n\r\n        if os.path.isfile(pkl_file_name) is False:\r\n            try:\r\n                tar_file_name = os.path.join(data_dir, '{}_{}.tar.gz'.format(self.dataset, self.city))\r\n                if os.path.isfile(tar_file_name) is False:\r\n                    print('Downloading data into', data_dir)\r\n                    wget.download('https://github.com/Di-Chai/UCTB_Data/blob/master/%s_%s.tar.gz?raw=true' %\r\n                                  (dataset, city), tar_file_name)\r\n                    print('Download succeed')\r\n                else:\r\n                    print('Found', tar_file_name)\r\n                tar = tarfile.open(tar_file_name, \"r:gz\")\r\n                file_names = tar.getnames()\r\n                for file_name in file_names:\r\n                    tar.extract(file_name, data_dir)\r\n                tar.close()\r\n                os.remove(tar_file_name)\r\n            except Exception as e:\r\n                print(e)\r\n                raise FileExistsError('Download Failed')\r\n\r\n        with open(pkl_file_name, 'rb') as f:\r\n            self.data = pickle.load(f)\r\n\r\n        # merge data\r\n        if self.MergeIndex > 1:\r\n            self.data['TimeFitness'] = int(self.data['TimeFitness'] * self.MergeIndex)\r\n            if len(self.data['Node']['TrafficNode']) > 0:\r\n                self.data['Node']['TrafficNode'] = self.merge_data(self.data['Node']['TrafficNode'], \"node\")\r\n            if len(self.data['Grid']['TrafficGrid']) > 0:\r\n                self.data['Grid']['TrafficGrid'] = self.merge_data(self.data['Grid']['TrafficGrid'], \"grid\")\r\n            if len(self.data['ExternalFeature']['Weather']) > 0:\r\n                self.data['ExternalFeature']['Weather'] = self.merge_data(self.data['ExternalFeature']['Weather'],\r\n                                                                          \"node\")\r\n\r\n        self.time_range = self.data['TimeRange']\r\n        self.time_fitness = self.data['TimeFitness']\r\n\r\n        self.node_traffic = self.data['Node']['TrafficNode']\r\n        self.node_monthly_interaction = self.data['Node']['TrafficMonthlyInteraction']\r\n        self.node_station_info = self.data['Node']['StationInfo']\r\n\r\n        self.grid_traffic = self.data['Grid']['TrafficGrid']\r\n        self.grid_lat_lng = self.data['Grid']['GridLatLng']\r\n\r\n        self.external_feature_weather = self.data['ExternalFeature']['Weather']\r\n\r\n    def merge_data(self, data, dataType):\r\n        if self.MergeWay == \"sum\":\r\n            func = np.sum\r\n        elif self.MergeWay == \"average\":\r\n            func = np.mean\r\n        elif self.MergeWay == \"max\":\r\n            func = np.max\r\n        else:\r\n            raise ValueError(\"Parameter MerWay should be sum or average\")\r\n        if data.shape[0] % self.MergeIndex is not 0:\r\n            raise ValueError(\"time_slots % MergeIndex should be zero\")\r\n\r\n        if dataType.lower() == \"node\":\r\n            new = np.zeros((data.shape[0] // self.MergeIndex, data.shape[1]), dtype=np.float32)\r\n            for new_ind, ind in enumerate(range(0, data.shape[0], self.MergeIndex)):\r\n                new[new_ind, :] = func(data[ind:ind + self.MergeIndex, :], axis=0)\r\n        elif dataType.lower() == \"grid\":\r\n            new = np.zeros((data.shape[0] // self.MergeIndex, data.shape[1], data.shape[2]), dtype=np.float32)\r\n            for new_ind, ind in enumerate(range(0, data.shape[0], self.MergeIndex)):\r\n                new[new_ind, :, :] = func(data[ind:ind + self.MergeIndex, :, :], axis=0)\r\n        return new"
  },
  {
    "path": "UCTB/evaluation/__init__.py",
    "content": "from . import metric"
  },
  {
    "path": "UCTB/evaluation/metric.py",
    "content": "\r\nimport numpy as np\r\n\r\ndef rmse(prediction, target, threshold=None):\r\n    \"\"\"\r\n    Root Mean Square Error (RMSE)\r\n    \r\n    Args:\r\n        prediction(ndarray): prediction with shape [batch_size, ...]\r\n        target(ndarray): same shape with prediction, [batch_size, ...]\r\n        threshold(float): data smaller or equal to threshold in target will be removed in computing the rmse\r\n    \"\"\"\r\n    if threshold is None:\r\n        return np.sqrt(np.mean(np.square(prediction - target)))\r\n    else:\r\n        return np.sqrt(np.dot(np.square(prediction - target).reshape([1, -1]),\r\n                              target.reshape([-1, 1]) > threshold) / np.sum(target > threshold))[0][0]\r\n\r\n\r\n\r\n\r\ndef trunc_rmse(prediction, target, threshold=0):\r\n    \r\n    \"\"\"\r\n    Root Mean Square Error with Truncation (trunc_RMSE)\r\n    Args:\r\n        prediction(ndarray): prediction with shape [batch_size, ...]\r\n        target(ndarray): same shape with prediction, [batch_size, ...]\r\n        threshold(float): data smaller or equal to threshold in target\r\n            will be replaced by threshold in computing the s_rmse\r\n    \"\"\"\r\n    predict_value = prediction.copy()\r\n    target_value = target.copy()\r\n    \r\n    predict_value[predict_value<=threshold] = threshold\r\n    target_value[target_value<=threshold] = threshold\r\n\r\n    return np.sqrt(np.mean(np.square(predict_value - target_value)))\r\n    \r\n    \r\n    \r\n\r\n\r\n\r\ndef mape(prediction, target, threshold=0):\r\n    \"\"\"\r\n    Mean Absolute Percentage Error (MAPE)\r\n    \r\n    Args:\r\n        prediction(ndarray): prediction with shape [batch_size, ...]\r\n        target(ndarray): same shape with prediction, [batch_size, ...]\r\n        threshold(float): data smaller than threshold in target will be removed in computing the mape.\r\n    \"\"\"\r\n    assert threshold > 0\r\n    return (np.dot((np.abs(prediction - target) / (target + (1 - (target > threshold)))).reshape([1, -1]),\r\n                   target.reshape([-1, 1]) > threshold) / np.sum(target > threshold))[0, 0]\r\n\r\n\r\ndef mae(prediction, target, threshold=None):\r\n    \"\"\"\r\n    Mean Absolute Error (MAE)\r\n    \r\n    Args:\r\n        prediction(ndarray): prediction with shape [batch_size, ...]\r\n        target(ndarray): same shape with prediction, [batch_size, ...]\r\n        threshold(float): data smaller or equal to threshold in target will be removed in computing the mae\r\n    \"\"\"\r\n    if threshold is None:\r\n        return np.mean(np.abs(prediction - target))\r\n    else:\r\n        return (np.dot(np.abs(prediction - target).reshape([1, -1]),\r\n                              target.reshape([-1, 1]) > threshold) / np.sum(target > threshold))[0, 0]\r\n\r\n\r\ndef trunc_mae(prediction, target, threshold=0):\r\n    \r\n    \"\"\"\r\n        Mean Absolute Error with Truncation (Trunc_MAE)\r\n    \r\n    Args:\r\n        prediction(ndarray): prediction with shape [batch_size, ...]\r\n        target(ndarray): same shape with prediction, [batch_size, ...]\r\n        threshold(float): data smaller or equal to threshold in target will be replaced in computing the mae\r\n    \"\"\"\r\n\r\n    predict_value=prediction.copy()\r\n    target_value = target.copy()\r\n\r\n    predict_value[predict_value<=threshold] = threshold\r\n    target_value[target_value<=threshold] = threshold\r\n\r\n    return np.mean(np.abs(predict_value - target_value))\r\n\r\n\r\n\r\n\r\ndef smape(prediction, target,threshold=0):\r\n    \"\"\"\r\n    Symmetric Mean Absolute Percentage Error (SMAPE)\r\n    \r\n    Args:\r\n        prediction(ndarray): prediction with shape [batch_size, ...]\r\n        target(ndarray): same shape with prediction, [batch_size, ...]\r\n        threshold(float): data smaller than threshold in target will be removed in computing the smape.\r\n    \"\"\"\r\n    assert threshold > 0\r\n\r\n    predict_value = prediction[prediction >threshold]\r\n    target_value = target[target >threshold]\r\n    return np.mean(np.abs(predict_value - target_value) / ((np.abs(predict_value) + np.abs(target_value))*0.5))\r\n\r\n\r\n\r\n\r\ndef trunc_smape(prediction, target, threshold=0):\r\n    \"\"\"\r\n    Symmetric Mean Absolute Percentage Error with Truncation (Trunc_SMAPE)\r\n    \r\n    Args:\r\n        prediction(ndarray): prediction with shape [batch_size, ...]\r\n        target(ndarray): same shape with prediction, [batch_size, ...]\r\n        threshold(float): data smaller than threshold in target will be replaced in computing the trunc_smape.\r\n    \"\"\"\r\n    predict_value = prediction.copy()\r\n    target_value = target.copy()\r\n    predict_value[predict_value<=threshold] = threshold\r\n    target_value[target_value<=threshold] = threshold\r\n    \r\n    return np.mean(np.abs(predict_value - target_value) / ((np.abs(predict_value) + np.abs(target_value))*0.5))\r\n   \r\n\r\n\r\n"
  },
  {
    "path": "UCTB/model/AGCRN.py",
    "content": "import torch\nimport torch.nn.functional as F\nimport torch.nn as nn\nimport torch\n\nclass AVWGCN(nn.Module):\n    def __init__(self, dim_in, dim_out, cheb_k, embed_dim):\n        super(AVWGCN, self).__init__()\n        self.cheb_k = cheb_k\n        self.weights_pool = nn.Parameter(torch.FloatTensor(embed_dim, cheb_k, dim_in, dim_out))\n        self.bias_pool = nn.Parameter(torch.FloatTensor(embed_dim, dim_out))\n    def forward(self, x, node_embeddings):\n        #x shaped[B, N, C], node_embeddings shaped [N, D] -> supports shaped [N, N]\n        #output shape [B, N, C]\n        node_num = node_embeddings.shape[0]\n        supports = F.softmax(F.relu(torch.mm(node_embeddings, node_embeddings.transpose(0, 1))), dim=1)\n        support_set = [torch.eye(node_num).to(supports.device), supports]\n        #default cheb_k = 3\n        for k in range(2, self.cheb_k):\n            support_set.append(torch.matmul(2 * supports, support_set[-1]) - support_set[-2])\n        supports = torch.stack(support_set, dim=0)\n        weights = torch.einsum('nd,dkio->nkio', node_embeddings, self.weights_pool)  #N, cheb_k, dim_in, dim_out\n        bias = torch.matmul(node_embeddings, self.bias_pool)                       #N, dim_out\n        x_g = torch.einsum(\"knm,bmc->bknc\", supports, x)      #B, cheb_k, N, dim_in\n        x_g = x_g.permute(0, 2, 1, 3)  # B, N, cheb_k, dim_in\n        x_gconv = torch.einsum('bnki,nkio->bno', x_g, weights) + bias     #b, N, dim_out\n        return x_gconv\n\nclass AVWDCRNN(nn.Module):\n    def __init__(self, node_num, dim_in, dim_out, cheb_k, embed_dim, num_layers=1):\n        super(AVWDCRNN, self).__init__()\n        assert num_layers >= 1, 'At least one DCRNN layer in the Encoder.'\n        self.node_num = node_num\n        self.input_dim = dim_in\n        self.num_layers = num_layers\n        self.dcrnn_cells = nn.ModuleList()\n        self.dcrnn_cells.append(AGCRNCell(node_num, dim_in, dim_out, cheb_k, embed_dim))\n        for _ in range(1, num_layers):\n            self.dcrnn_cells.append(AGCRNCell(node_num, dim_out, dim_out, cheb_k, embed_dim))\n\n    def forward(self, x, init_state, node_embeddings):\n        #shape of x: (B, T, N, D)\n        #shape of init_state: (num_layers, B, N, hidden_dim)\n        assert x.shape[2] == self.node_num and x.shape[3] == self.input_dim\n        seq_length = x.shape[1]\n        current_inputs = x\n        output_hidden = []\n        for i in range(self.num_layers):\n            state = init_state[i]\n            inner_states = []\n            for t in range(seq_length):\n                state = self.dcrnn_cells[i](current_inputs[:, t, :, :], state, node_embeddings)\n                inner_states.append(state)\n            output_hidden.append(state)\n            current_inputs = torch.stack(inner_states, dim=1)\n        #current_inputs: the outputs of last layer: (B, T, N, hidden_dim)\n        #output_hidden: the last state for each layer: (num_layers, B, N, hidden_dim)\n        #last_state: (B, N, hidden_dim)\n        return current_inputs, output_hidden\n\n\n    def init_hidden(self, batch_size):\n        init_states = []\n        for i in range(self.num_layers):\n            init_states.append(self.dcrnn_cells[i].init_hidden_state(batch_size))\n        return torch.stack(init_states, dim=0)      #(num_layers, B, N, hidden_dim)\n\nclass AGCRN(nn.Module):\n    \"\"\"\n\n    References:\n        - `Adaptive graph convolutional recurrent network for traffic forecasting.\n          <https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf>`_.\n        - `A PyTorch implementation of the AGCRN model  (LeiBAI)\n          <https://github.com/LeiBAI/AGCRN>`_.\n\n    Args:\n        num_node(int): Number of nodes.\n        input_dim(int): Input feature dimension.\n        hidden_dim(int): Number of hidden units of RNN.\n        output_dim(int): Number of dimension of output.\n        pred_step(int): Number of steps to predict.\n        num_layers(int): Number of layers of AGCRNCell.\n        default_graph(bool): Whether to use default graph or not.\n        embed_dim(int): Number of dimension of embedding.\n        cheb_k(int): Order of chebyshev polynomial.\n    \"\"\"\n    def __init__(self, num_node,input_dim,hidden_dim,output_dim,pred_step,num_layers,default_graph,embed_dim,cheb_k):\n        super(AGCRN, self).__init__()\n        self.num_node = num_node\n        self.input_dim = input_dim\n        self.hidden_dim = hidden_dim\n        self.output_dim = output_dim\n        # 输出变量维度\n        self.pred_step = pred_step\n        # 预测步长\n        self.num_layers = num_layers\n\n        self.default_graph = default_graph\n        self.node_embeddings = nn.Parameter(torch.randn(self.num_node, embed_dim), requires_grad=True)\n\n        self.encoder = AVWDCRNN(self.num_node, self.input_dim, self.hidden_dim, cheb_k,\n                                embed_dim, self.num_layers)\n\n        #predictor\n        self.end_conv = nn.Conv2d(1, self.pred_step * self.output_dim, kernel_size=(1, self.hidden_dim), bias=True)\n\n    def forward(self, source, targets, teacher_forcing_ratio=0.5):\n        #source: B, T_1, N, D\n        #target: B, T_2, N, D\n        #supports = F.softmax(F.relu(torch.mm(self.nodevec1, self.nodevec1.transpose(0,1))), dim=1)\n\n        init_state = self.encoder.init_hidden(source.shape[0])\n        output, _ = self.encoder(source, init_state, self.node_embeddings)      #B, T, N, hidden\n        output = output[:, -1:, :, :]                                   #B, 1, N, hidden\n\n        #CNN based predictor\n        output = self.end_conv((output))                         #B, T*C, N, 1\n        output = output.squeeze(-1).reshape(-1, self.pred_step, self.output_dim, self.num_node)\n        output = output.permute(0, 1, 3, 2)                             #B, T, N, C\n\n        return output\n\nclass AGCRNCell(nn.Module):\n    def __init__(self, node_num, dim_in, dim_out, cheb_k, embed_dim):\n        super(AGCRNCell, self).__init__()\n        self.node_num = node_num\n        self.hidden_dim = dim_out\n        self.gate = AVWGCN(dim_in+self.hidden_dim, 2*dim_out, cheb_k, embed_dim)\n        self.update = AVWGCN(dim_in+self.hidden_dim, dim_out, cheb_k, embed_dim)\n\n    def forward(self, x, state, node_embeddings):\n        #x: B, num_node, input_dim\n        #state: B, num_node, hidden_dim\n        state = state.to(x.device)\n        input_and_state = torch.cat((x, state), dim=-1)\n        z_r = torch.sigmoid(self.gate(input_and_state, node_embeddings))\n        z, r = torch.split(z_r, self.hidden_dim, dim=-1)\n        candidate = torch.cat((x, z*state), dim=-1)\n        hc = torch.tanh(self.update(candidate, node_embeddings))\n        h = r*state + (1-r)*hc\n        return h\n\n    def init_hidden_state(self, batch_size):\n        return torch.zeros(batch_size, self.node_num, self.hidden_dim)\n"
  },
  {
    "path": "UCTB/model/ARIMA.py",
    "content": "import numpy as np\r\nimport pandas as pd\r\nimport statsmodels.api as sm\r\n\r\nimport warnings\r\nwarnings.filterwarnings(\"ignore\")\r\n\r\n\r\nclass ARIMA(object):\r\n    \"\"\"ARIMA is a generalization of an ARMA (Autoregressive Moving Average) model, used in predicting \r\n    future points in time series analysis.\r\n\r\n    Since there may be three kinds of series data as closeness, period and trend history, this class\r\n    trains three different ARIMA models for each node according  to the three kinds of history data, \r\n    and returns average of the predicted values by the models in prediction.\r\n\r\n    Args:\r\n        time_sequence(array_like): The observation value of time_series.\r\n        order(iterable): It stores the (p, d, q) orders of the model for the number of AR parameters\r\n            , differences, MA parameters. If set to None, ARIMA class will calculate the orders for \r\n            each series based on max_ar, max_ma and max_d. Default: None\r\n        seasonal_order(iterable): It stores the (P,D,Q,s) order of the seasonal ARIMA model for the\r\n            AR parameters, differences, MA parameters, and periodicity. `s` is an integer giving the \r\n            periodicity (number of periods in season).\r\n        max_ar(int): Maximum number of AR lags to use. Default: 6\r\n        max_ma(int): Maximum number of MA lags to use. Default: 4\r\n        max_d(int): Maximum number of degrees of differencing. Default: 2\r\n\r\n    Attribute:\r\n        order(iterable): (p, d, q) orders for ARIMA model. \r\n        seasonal_order(iterable): (P,D,Q,s) order for seasonal ARIMA model. \r\n        model_res(): Fit method for likelihood based models. \r\n    \"\"\"\r\n\r\n    def __init__(self, time_sequence, order=None, seasonal_order=(0, 0, 0, 0), max_ar=6, max_ma=4, max_d=2):\r\n\r\n        self.seasonal_order = seasonal_order\r\n        auto_order = self.get_order(time_sequence, order, max_ar=max_ar, max_ma=max_ma, max_d=max_d)\r\n        model = sm.tsa.SARIMAX(time_sequence, order=auto_order, seasonal_order=self.seasonal_order)\r\n        model_res = model.fit(disp=False)\r\n        self.order = auto_order\r\n        self.model_res = model_res\r\n\r\n    def get_order(self, series, order=None, max_ar=6, max_ma=2, max_d=2):\r\n        '''\r\n        If order is None, it simply returns order, otherwise, it calculates the (p, d, q) orders \r\n        for the series data based on max_ar, max_ma and max_d.\r\n        '''\r\n\r\n        def stationary(series):\r\n            t = ARIMA.adf_test(series, verbose=False)\r\n            if t[0] < t[4]['1%']:\r\n                return True\r\n            else:\r\n                return False\r\n\r\n        if order is None:\r\n            order_i = 0\r\n            while not stationary(np.diff(series, order_i)):\r\n                order_i += 1\r\n                if order_i > max_d:\r\n                    break\r\n            order = sm.tsa.stattools.arma_order_select_ic(np.diff(series, order_i),\r\n                                                          max_ar=max_ar, max_ma=max_ma,\r\n                                                          ic=['aic']).aic_min_order\r\n            order = list(order)\r\n            order.insert(1, order_i)\r\n\r\n        return order\r\n\r\n    @staticmethod\r\n    def adf_test(time_series, max_lags=None, verbose=True):\r\n        '''\r\n        Augmented Dickey–Fuller test. The Augmented Dickey-Fuller test can be used to test for \r\n        a unit root in a univariate process in the presence of serial correlation.\r\n        '''\r\n        t = sm.tsa.stattools.adfuller(time_series, maxlag=max_lags)\r\n        if verbose:\r\n            output = pd.DataFrame(\r\n                index=['Test Statistic Value',\r\n                       \"p-value\",\r\n                       \"Lags Used\",\r\n                       \"Number of Observations Used\",\r\n                       \"Critical Value(1%)\",\r\n                       \"Critical Value(5%)\", \"Critical Value(10%)\"], columns=['value'])\r\n            output['value']['Test Statistic Value'] = t[0]\r\n            output['value']['p-value'] = t[1]\r\n            output['value']['Lags Used'] = t[2]\r\n            output['value']['Number of Observations Used'] = t[3]\r\n            output['value']['Critical Value(1%)'] = t[4]['1%']\r\n            output['value']['Critical Value(5%)'] = t[4]['5%']\r\n            output['value']['Critical Value(10%)'] = t[4]['10%']\r\n            print(output)\r\n        return t\r\n\r\n    def predict(self, time_sequences, forecast_step=1):\r\n        '''\r\n        Argues:\r\n            time_sequences: The input time_series features.\r\n            forecast_step: The number of predicted future steps. Default: 1\r\n        \r\n        :return: Prediction results with shape of (len(time_sequence)/forecast_step,forecast_step=,1).\r\n        :type: np.ndarray\r\n        '''\r\n        result = []\r\n        \"\"\" origin predict method, output shape is [math.ceil(len(time_sequences) / forecast_step), forecast_step]\r\n        for i in range(0, len(time_sequences), forecast_step):\r\n            fs = forecast_step if ((i + forecast_step) < len(time_sequences)) else (len(time_sequences) - i)\r\n            model = sm.tsa.SARIMAX(time_sequences[i], order=self.order, seasonal_order=self.seasonal_order)\r\n            model_res = model.filter(self.model_res.params)\r\n            p = model_res.forecast(fs).reshape([-1, 1])\r\n            result.append(p)\r\n        \"\"\"\r\n        # new predict method, output shape is [len(time_sequences), forecast_step]\r\n        for i in range(len(time_sequences)):\r\n            model = sm.tsa.SARIMAX(time_sequences[i], order=self.order, seasonal_order=self.seasonal_order)\r\n            model_res = model.filter(self.model_res.params)\r\n            p = model_res.forecast(forecast_step)\r\n            p = p.reshape([-1, forecast_step])\r\n            result.append(p)\r\n        if forecast_step != 1:\r\n            result = np.concatenate(result, axis=0)\r\n        return np.array(result, dtype=np.float32)"
  },
  {
    "path": "UCTB/model/ASTGCN.py",
    "content": "# -*- coding:utf-8 -*-\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport numpy as np\nimport torch.utils.data\n\n\nclass Spatial_Attention_layer(nn.Module):\n    '''\n    compute spatial attention scores\n    '''\n    def __init__(self, DEVICE, in_channels, num_of_vertices, num_of_timesteps):\n        super(Spatial_Attention_layer, self).__init__()\n        self.W1 = nn.Parameter(torch.FloatTensor(num_of_timesteps).to(DEVICE))\n        self.W2 = nn.Parameter(torch.FloatTensor(in_channels, num_of_timesteps).to(DEVICE))\n        self.W3 = nn.Parameter(torch.FloatTensor(in_channels).to(DEVICE))\n        self.bs = nn.Parameter(torch.FloatTensor(1, num_of_vertices, num_of_vertices).to(DEVICE))\n        self.Vs = nn.Parameter(torch.FloatTensor(num_of_vertices, num_of_vertices).to(DEVICE))\n\n\n    def forward(self, x):\n        '''\n        :param x: (batch_size, N, F_in, T)\n        :return: (B,N,N)\n        '''\n\n        lhs = torch.matmul(torch.matmul(x, self.W1), self.W2)  # (b,N,F,T)(T)->(b,N,F)(F,T)->(b,N,T)\n\n        rhs = torch.matmul(self.W3, x).transpose(-1, -2)  # (F)(b,N,F,T)->(b,N,T)->(b,T,N)\n\n        product = torch.matmul(lhs, rhs)  # (b,N,T)(b,T,N) -> (B, N, N)\n\n        S = torch.matmul(self.Vs, torch.sigmoid(product + self.bs))  # (N,N)(B, N, N)->(B,N,N)\n\n        S_normalized = F.softmax(S, dim=1)\n\n        return S_normalized\n\n\nclass cheb_conv_withSAt(nn.Module):\n    '''\n    K-order chebyshev graph convolution\n    '''\n\n    def __init__(self, K, cheb_polynomials, in_channels, out_channels):\n        '''\n        :param K: int\n        :param in_channles: int, num of channels in the input sequence\n        :param out_channels: int, num of channels in the output sequence\n        '''\n        super(cheb_conv_withSAt, self).__init__()\n        self.K = K\n        self.cheb_polynomials = cheb_polynomials\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.DEVICE = cheb_polynomials[0].device\n        self.Theta = nn.ParameterList([nn.Parameter(torch.FloatTensor(in_channels, out_channels).to(self.DEVICE)) for _ in range(K)])\n\n    def forward(self, x, spatial_attention):\n        '''\n        Chebyshev graph convolution operation\n        :param x: (batch_size, N, F_in, T)\n        :return: (batch_size, N, F_out, T)\n        '''\n\n        batch_size, num_of_vertices, in_channels, num_of_timesteps = x.shape\n\n        outputs = []\n\n        for time_step in range(num_of_timesteps):\n\n            graph_signal = x[:, :, :, time_step]  # (b, N, F_in)\n\n            output = torch.zeros(batch_size, num_of_vertices, self.out_channels).to(self.DEVICE)  # (b, N, F_out)\n\n            for k in range(self.K):\n\n                T_k = self.cheb_polynomials[k]  # (N,N)\n\n                T_k_with_at = T_k.mul(spatial_attention)   # (N,N)*(N,N) = (N,N) 多行和为1, 按着列进行归一化\n\n                theta_k = self.Theta[k]  # (in_channel, out_channel)\n\n                rhs = T_k_with_at.permute(0, 2, 1).matmul(graph_signal)  # (N, N)(b, N, F_in) = (b, N, F_in) 因为是左乘，所以多行和为1变为多列和为1，即一行之和为1，进行左乘\n\n                output = output + rhs.matmul(theta_k)  # (b, N, F_in)(F_in, F_out) = (b, N, F_out)\n\n            outputs.append(output.unsqueeze(-1))  # (b, N, F_out, 1)\n\n        return F.relu(torch.cat(outputs, dim=-1))  # (b, N, F_out, T)\n\n\nclass Temporal_Attention_layer(nn.Module):\n    def __init__(self, DEVICE, in_channels, num_of_vertices, num_of_timesteps):\n        super(Temporal_Attention_layer, self).__init__()\n        self.U1 = nn.Parameter(torch.FloatTensor(num_of_vertices).to(DEVICE))\n        self.U2 = nn.Parameter(torch.FloatTensor(in_channels, num_of_vertices).to(DEVICE))\n        self.U3 = nn.Parameter(torch.FloatTensor(in_channels).to(DEVICE))\n        self.be = nn.Parameter(torch.FloatTensor(1, num_of_timesteps, num_of_timesteps).to(DEVICE))\n        self.Ve = nn.Parameter(torch.FloatTensor(num_of_timesteps, num_of_timesteps).to(DEVICE))\n\n    def forward(self, x):\n        '''\n        :param x: (batch_size, N, F_in, T)\n        :return: (B, T, T)\n        '''\n        _, num_of_vertices, num_of_features, num_of_timesteps = x.shape\n\n        lhs = torch.matmul(torch.matmul(x.permute(0, 3, 2, 1), self.U1), self.U2)\n        # x:(B, N, F_in, T) -> (B, T, F_in, N)\n        # (B, T, F_in, N)(N) -> (B,T,F_in)\n        # (B,T,F_in)(F_in,N)->(B,T,N)\n\n        rhs = torch.matmul(self.U3, x)  # (F)(B,N,F,T)->(B, N, T)\n\n        product = torch.matmul(lhs, rhs)  # (B,T,N)(B,N,T)->(B,T,T)\n\n        E = torch.matmul(self.Ve, torch.sigmoid(product + self.be))  # (B, T, T)\n\n        E_normalized = F.softmax(E, dim=1)\n\n        return E_normalized\n\n\nclass cheb_conv(nn.Module):\n    '''\n    K-order chebyshev graph convolution\n    '''\n\n    def __init__(self, K, cheb_polynomials, in_channels, out_channels):\n        '''\n        :param K: int\n        :param in_channles: int, num of channels in the input sequence\n        :param out_channels: int, num of channels in the output sequence\n        '''\n        super(cheb_conv, self).__init__()\n        self.K = K\n        self.cheb_polynomials = cheb_polynomials\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.DEVICE = cheb_polynomials[0].device\n        self.Theta = nn.ParameterList([nn.Parameter(torch.FloatTensor(in_channels, out_channels).to(self.DEVICE)) for _ in range(K)])\n\n    def forward(self, x):\n        '''\n        Chebyshev graph convolution operation\n        :param x: (batch_size, N, F_in, T)\n        :return: (batch_size, N, F_out, T)\n        '''\n\n        batch_size, num_of_vertices, in_channels, num_of_timesteps = x.shape\n\n        outputs = []\n\n        for time_step in range(num_of_timesteps):\n\n            graph_signal = x[:, :, :, time_step]  # (b, N, F_in)\n\n            output = torch.zeros(batch_size, num_of_vertices, self.out_channels).to(self.DEVICE)  # (b, N, F_out)\n\n            for k in range(self.K):\n\n                T_k = self.cheb_polynomials[k]  # (N,N)\n\n                theta_k = self.Theta[k]  # (in_channel, out_channel)\n\n                rhs = graph_signal.permute(0, 2, 1).matmul(T_k).permute(0, 2, 1)\n\n                output = output + rhs.matmul(theta_k)\n\n            outputs.append(output.unsqueeze(-1))\n\n        return F.relu(torch.cat(outputs, dim=-1))\n\n\nclass ASTGCN_block(nn.Module):\n\n    def __init__(self, DEVICE, in_channels, K, nb_chev_filter, nb_time_filter, time_strides, cheb_polynomials, num_of_vertices, num_of_timesteps):\n        super(ASTGCN_block, self).__init__()\n        self.TAt = Temporal_Attention_layer(DEVICE, in_channels, num_of_vertices, num_of_timesteps)\n        self.SAt = Spatial_Attention_layer(DEVICE, in_channels, num_of_vertices, num_of_timesteps)\n        self.cheb_conv_SAt = cheb_conv_withSAt(K, cheb_polynomials, in_channels, nb_chev_filter)\n        self.time_conv = nn.Conv2d(nb_chev_filter, nb_time_filter, kernel_size=(1, 3), stride=(1, time_strides), padding=(0, 1))\n        self.residual_conv = nn.Conv2d(in_channels, nb_time_filter, kernel_size=(1, 1), stride=(1, time_strides))\n        self.ln = nn.LayerNorm(nb_time_filter)  #需要将channel放到最后一个维度上\n\n    def forward(self, x):\n        '''\n        :param x: (batch_size, N, F_in, T)\n        :return: (batch_size, N, nb_time_filter, T)\n        '''\n        batch_size, num_of_vertices, num_of_features, num_of_timesteps = x.shape\n\n        # TAt\n        temporal_At = self.TAt(x)  # (b, T, T)\n\n        x_TAt = torch.matmul(x.reshape(batch_size, -1, num_of_timesteps), temporal_At).reshape(batch_size, num_of_vertices, num_of_features, num_of_timesteps)\n\n        # SAt\n        spatial_At = self.SAt(x_TAt)\n\n        # cheb gcn\n        spatial_gcn = self.cheb_conv_SAt(x, spatial_At)  # (b,N,F,T)\n        # spatial_gcn = self.cheb_conv(x)\n\n        # convolution along the time axis\n        time_conv_output = self.time_conv(spatial_gcn.permute(0, 2, 1, 3))  # (b,N,F,T)->(b,F,N,T) 用(1,3)的卷积核去做->(b,F,N,T)\n\n        # residual shortcut\n        x_residual = self.residual_conv(x.permute(0, 2, 1, 3))  # (b,N,F,T)->(b,F,N,T) 用(1,1)的卷积核去做->(b,F,N,T)\n\n        x_residual = self.ln(F.relu(x_residual + time_conv_output).permute(0, 3, 2, 1)).permute(0, 2, 3, 1)\n        # (b,F,N,T)->(b,T,N,F) -ln-> (b,T,N,F)->(b,N,F,T)\n\n        return x_residual\n\n\nclass ASTGCN_submodule(nn.Module):\n    \"\"\"\n\n    References:\n        - `Attention based spatial-temporal graph convolutional networks for traffic flow forecasting..\n          <https://ojs.aaai.org/index.php/AAAI/article/view/3881>`_.\n        - `A PyTorch implementation of the ASTGCN model  (guoshnBJTU)\n          <https://github.com/guoshnBJTU/ASTGCN-r-pytorch>`_.\n\n    Args:\n        DEVICE(torch.device): Which device use to train.\n        num_blocks(int): Number of blocks.\n        in_channels(int): Number of input channels.\n        K(int): Order of chebyshev polynomial.\n        num_chev_filter(int): Number of chebyshev filter.\n        num_time_filter(int): Number of time filter.\n        time_strides(int): Number of time strides.\n        cheb_polynomials(int): Chebyshev Polynomials.\n        pred_step(int): Number of steps of prediction.\n        len_input(int): Number of steps of sequence input.\n        num_node(int): Number of nodes.\n    \"\"\"\n\n    def __init__(self, DEVICE, num_blocks, in_channels, K, num_chev_filter, num_time_filter, time_strides, cheb_polynomials, pred_step, len_input, num_node):\n\n        super(ASTGCN_submodule, self).__init__()\n\n        self.BlockList = nn.ModuleList([ASTGCN_block(DEVICE, in_channels, K, num_chev_filter, num_time_filter, time_strides, cheb_polynomials, num_node, len_input)])\n\n        self.BlockList.extend([ASTGCN_block(DEVICE, num_time_filter, K, num_chev_filter, num_time_filter, 1, cheb_polynomials, num_node, len_input//time_strides) for _ in range(num_blocks-1)])\n\n        self.final_conv = nn.Conv2d(int(len_input/time_strides), pred_step, kernel_size=(1, num_time_filter))\n\n        self.DEVICE = DEVICE\n\n        self.to(DEVICE)\n\n    def forward(self, x):\n        '''\n        :param x: (B, N_nodes, F_in, T_in)\n        :return: (B, N_nodes, T_out)\n        '''\n        for block in self.BlockList:\n            x = block(x)\n\n        output = self.final_conv(x.permute(0, 3, 1, 2))[:, :, :, -1].permute(0, 2, 1)\n        # (b,N,F,T)->(b,T,N,F)-conv<1,F>->(b,c_out*T,N,1)->(b,c_out*T,N)->(b,N,T)\n\n        return output\n\n\ndef make_model(DEVICE, nb_block, in_channels, K, nb_chev_filter, nb_time_filter, time_strides, L_tilde, num_for_predict, len_input, num_of_vertices):\n    '''\n\n    :param DEVICE:\n    :param nb_block:\n    :param in_channels:\n    :param K:\n    :param nb_chev_filter:\n    :param nb_time_filter:\n    :param time_strides:\n    :param cheb_polynomials:\n    :param nb_predict_step:\n    :param len_input\n    :return:\n    '''\n    cheb_polynomials = [torch.from_numpy(i).type(torch.FloatTensor).to(DEVICE) for i in cheb_polynomial(L_tilde, K)]\n    model = ASTGCN_submodule(DEVICE, nb_block, in_channels, K, nb_chev_filter, nb_time_filter, time_strides, cheb_polynomials, num_for_predict, len_input, num_of_vertices)\n\n    for p in model.parameters():\n        if p.dim() > 1:\n            nn.init.xavier_uniform_(p)\n        else:\n            nn.init.uniform_(p)\n\n    return model\n\n\n\ndef cheb_polynomial(L_tilde, K):\n    '''\n    compute a list of chebyshev polynomials from T_0 to T_{K-1}\n\n    Parameters\n    ----------\n    L_tilde: scaled Laplacian, np.ndarray, shape (N, N)\n\n    K: the maximum order of chebyshev polynomials\n\n    Returns\n    ----------\n    cheb_polynomials: list(np.ndarray), length: K, from T_0 to T_{K-1}\n\n    '''\n\n    N = L_tilde.shape[0]\n\n    cheb_polynomials = [np.identity(N), L_tilde.copy()]\n\n    for i in range(2, K):\n        cheb_polynomials.append(2 * L_tilde * cheb_polynomials[i - 1] - cheb_polynomials[i - 2])\n\n    return cheb_polynomials\n\n\n\n"
  },
  {
    "path": "UCTB/model/DCRNN.py",
    "content": "import tensorflow as tf\n\nfrom ..model_unit import BaseModel\nfrom ..model_unit import DCGRUCell\n\nfrom tensorflow.contrib import legacy_seq2seq\n\n\nclass DCRNN(BaseModel):\n    \"\"\"\n\n    References:\n        - `Diffusion convolutional recurrent neural network: Data-driven traffic forecasting (Li Yaguang, et al., 2017)\n          <https://arxiv.org/pdf/1707.01926.pdf>`_.\n        - `A TensorFlow implementation of Diffusion Convolutional Recurrent Neural Network (liyaguang)\n          <https://github.com/liyaguang/DCRNN>`_.\n\n    Args:\n        num_node(int): Number of nodes in the graph, e.g. number of stations in NYC-Bike dataset.\n        num_diffusion_matrix: Number of diffusion matrix used in model.\n        num_rnn_units: Number of RNN units.\n        num_rnn_layers: Number of RNN layers\n        max_diffusion_step: Number of diffusion steps\n        seq_len: Input sequence length\n        use_curriculum_learning(bool): model's prediction (True) or the previous ground truth in training (False).\n        input_dim: Dimension of the input feature\n        output_dim: Dimension of the output feature\n        cl_decay_steps: When use_curriculum_learning=True, cl_decay_steps is used to adjust the ratio of using ground\n            true labels, where with more training steps, the ratio drops.\n        target_len(int): Output sequence length.\n        lr(float): Learning rate\n        epsilon: epsilon in Adam\n        optimizer_name(str): 'sgd' or 'Adam' optimizer\n        code_version(str): Current version of this model code, which will be used as filename for saving the model\n        model_dir(str): The directory to store model files. Default:'model_dir'.\n        gpu_device(str): To specify the GPU to use. Default: '0'.\n    \"\"\"\n    def __init__(self,\n                 num_node,\n                 num_diffusion_matrix,\n                 num_rnn_units=64,\n                 num_rnn_layers=1,\n                 max_diffusion_step=2,\n                 seq_len=6,\n                 use_curriculum_learning=False,\n                 input_dim=1,\n                 output_dim=1,\n                 cl_decay_steps=1000,\n                 target_len=1,\n                 lr=1e-4,\n                 epsilon=1e-3,\n                 optimizer_name='Adam',\n                 code_version='DCRNN-QuickStart',\n                 model_dir='model_dir',\n                 gpu_device='0', **kwargs):\n\n        super(DCRNN, self).__init__(code_version=code_version, model_dir=model_dir, gpu_device=gpu_device)\n\n        self._num_node = num_node\n        self._num_diffusion_matrix = num_diffusion_matrix\n        self._num_rnn_units = num_rnn_units\n        self._num_rnn_layers = num_rnn_layers\n        self._max_diffusion_step = max_diffusion_step\n        self._seq_len = seq_len\n        self._use_curriculum_learning = use_curriculum_learning\n        self._input_dim = input_dim\n        self._output_dim = output_dim\n        self._target_len = target_len\n        self._cl_decay_steps = cl_decay_steps\n        self._optimizer_name = optimizer_name\n        self._lr = lr\n        # self._batch_size = batch_size\n        self._epsilon = epsilon\n\n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            inputs = tf.placeholder(tf.float32, shape=(None, self._seq_len,\n                                                       self._num_node, self._input_dim), name='inputs')\n            labels = tf.placeholder(tf.float32, shape=(None, self._target_len,\n                                                       self._num_node, self._output_dim), name='labels')\n\n            diffusion_matrix = tf.placeholder(tf.float32, shape=(self._num_diffusion_matrix, self._num_node,\n                                                                 self._num_node), name='diffusion_matrix')\n\n            batch_size = tf.shape(inputs)[0]\n\n            self._input['inputs'] = inputs.name\n            self._input['target'] = labels.name\n            self._input['diffusion_matrix'] = diffusion_matrix.name\n\n            go_symbol = tf.zeros(shape=(tf.shape(inputs)[0], self._num_node * self._output_dim))\n\n            cell = DCGRUCell(self._num_rnn_units, self._input_dim, self._num_diffusion_matrix, diffusion_matrix,\n                             max_diffusion_step=self._max_diffusion_step, num_node=self._num_node)\n\n            cell_with_projection = DCGRUCell(self._num_rnn_units, self._input_dim,\n                                             self._num_diffusion_matrix, diffusion_matrix,\n                                             max_diffusion_step=self._max_diffusion_step,\n                                             num_node=self._num_node, num_proj=self._output_dim)\n\n            encoding_cells = [cell] * self._num_rnn_layers\n            decoding_cells = [cell] * (self._num_rnn_layers - 1) + [cell_with_projection]\n            encoding_cells = tf.contrib.rnn.MultiRNNCell(encoding_cells, state_is_tuple=True)\n            decoding_cells = tf.contrib.rnn.MultiRNNCell(decoding_cells, state_is_tuple=True)\n\n            global_step = tf.train.get_or_create_global_step()\n\n            # Outputs: (batch_size, timesteps, num_node, output_dim)\n            with tf.variable_scope('DCRNN_SEQ'):\n                inputs_unstack = tf.unstack(tf.reshape(inputs, (batch_size,\n                                                                self._seq_len, self._num_node * self._input_dim)),\n                                            axis=1)\n                labels_unstack = tf.unstack(\n                    tf.reshape(labels[..., :self._output_dim],\n                               (batch_size, self._target_len, self._num_node * self._output_dim)), axis=1)\n                labels_unstack.insert(0, go_symbol)\n\n                def _compute_sampling_threshold(global_step, k):\n                    \"\"\"\n                    Computes the sampling probability for scheduled sampling using inverse sigmoid.\n                    global_step:\n                    k:\n                    :return:\n                    \"\"\"\n                    return tf.cast(k / (k + tf.exp(global_step / k)), tf.float32)\n\n                def _loop_function_train(prev, i):\n                    # Return either the model's prediction or the previous ground truth in training.\n                    if self._use_curriculum_learning:\n                        c = tf.random_uniform((), minval=0, maxval=1.)\n                        threshold = _compute_sampling_threshold(global_step, self._cl_decay_steps)\n                        result = tf.cond(tf.less(c, threshold), lambda: labels_unstack[i], lambda: prev)\n                    else:\n                        result = labels_unstack[i]\n                    return result\n\n                def _loop_function_test(prev, i):\n                    # Return the prediction of the model in testing.\n                    return prev\n\n                a, enc_state = tf.contrib.rnn.static_rnn(encoding_cells, inputs_unstack, dtype=tf.float32)\n\n                with tf.variable_scope('train', reuse=False):\n                    train_outputs, _ = legacy_seq2seq.rnn_decoder(labels_unstack, enc_state, decoding_cells,\n                                                                  loop_function=_loop_function_train)\n                with tf.variable_scope('text', reuse=True):\n                    test_outputs, _ = legacy_seq2seq.rnn_decoder(labels_unstack, enc_state, decoding_cells,\n                                                                 loop_function=_loop_function_test)\n\n            # Project the output to output_dim.\n            train_outputs = tf.stack(train_outputs[:-1], axis=1)\n            test_outputs = tf.stack(test_outputs[:-1], axis=1)\n\n            # Configure optimizer\n            optimizer = tf.train.AdamOptimizer(self._lr, epsilon=float(self._epsilon))\n\n            if self._optimizer_name == 'sgd':\n                optimizer = tf.train.GradientDescentOptimizer(self._lr)\n\n            loss = tf.sqrt(tf.reduce_mean(tf.square(train_outputs - labels[:, :, :, 0])))\n\n            train_op = optimizer.minimize(loss)\n\n            self._output['prediction'] = test_outputs.name\n            self._output['loss'] = loss.name\n            self._op['train_op'] = train_op.name\n\n        super(DCRNN, self).build(init_vars=init_vars, max_to_keep=5)\n\n    # Define your '_get_feed_dict function‘, map your input to the tf-model\n    def _get_feed_dict(self,\n                       inputs,\n                       diffusion_matrix,\n                       target=None,):\n        feed_dict = {\n            'inputs': inputs,\n            'diffusion_matrix': diffusion_matrix,\n        }\n        if target is not None:\n            feed_dict['target'] = target\n        return feed_dict\n"
  },
  {
    "path": "UCTB/model/DeepST.py",
    "content": "import os\r\nimport tensorflow as tf\r\n\r\nfrom ..model_unit import BaseModel\r\n\r\n\r\nclass DeepST(BaseModel):\r\n    \"\"\"Deep learning-based prediction model for Spatial-Temporal data (DeepST)\r\n\r\n    DeepST is composed of three components: 1) temporal dependent\r\n    instances: describing temporal closeness, period and seasonal\r\n    trend; 2) convolutional neural networks: capturing near and\r\n    far spatial dependencies; 3) early and late fusions: fusing\r\n    similar and different domains' data.\r\n\r\n    Reference:\r\n        - `DNN-Based Prediction Model for Spatial-Temporal Data (Junbo Zhang et al., 2016)\r\n          <https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf>`_.\r\n\r\n    Args:\r\n        closeness_len (int): The length of closeness data history. The former consecutive ``closeness_len`` time slots\r\n            of data will be used as closeness history.\r\n        period_len (int): The length of period data history. The data of exact same time slots in former consecutive\r\n            ``period_len`` days will be used as period history.\r\n        trend_len (int): The length of trend data history. The data of exact same time slots in former consecutive\r\n            ``trend_len`` weeks (every seven days) will be used as trend history.\r\n        width (int): The width of grid data.\r\n        height (int): The height of grid data.\r\n        externai_dim (int): Number of dimensions of external data.\r\n        kernel_size (int): Kernel size in Convolutional neural networks. Default: 3\r\n        num_conv_filters (int):  the Number of filters in the convolution. Default: 64\r\n        lr (float): Learning rate. Default: 1e-5\r\n        code_version (str): Current version of this model code.\r\n        model_dir (str): The directory to store model files. Default:'model_dir'\r\n        gpu_device (str): To specify the GPU to use. Default: '0'\r\n    \"\"\"\r\n    def __init__(self,\r\n                 closeness_len,\r\n                 period_len,\r\n                 trend_len,\r\n                 width,\r\n                 height,\r\n                 external_dim,\r\n                 kernel_size=3,\r\n                 num_conv_filters=64,\r\n                 lr=1e-5,\r\n                 code_version='QuickStart-DeepST',\r\n                 model_dir='model_dir',\r\n                 gpu_device='0'):\r\n        \r\n        super(DeepST, self).__init__(code_version=code_version, model_dir=model_dir, gpu_device=gpu_device)\r\n\r\n        self._width = width\r\n        self._height = height\r\n\r\n        self._closeness_len = closeness_len\r\n        self._period_len = period_len\r\n        self._trend_len = trend_len\r\n\r\n        self._external_dim = external_dim\r\n        self._lr = lr\r\n        self._kernel_size = kernel_size\r\n        self._num_conv_filters = num_conv_filters\r\n\r\n        self._graph = tf.Graph()\r\n        self._GPU_DEVICE = gpu_device\r\n\r\n        self._input = {}\r\n        self._output = {}\r\n        self._op = {}\r\n        self._variable_init = None\r\n        self._saver = None\r\n        self._model_dir = model_dir\r\n\r\n        # GPU Config\r\n        os.environ[\"CUDA_DEVICE_ORDER\"] = \"PCI_BUS_ID\"\r\n        os.environ[\"CUDA_VISIBLE_DEVICES\"] = self._GPU_DEVICE\r\n        self._config = tf.ConfigProto()\r\n        self._config.gpu_options.allow_growth = True\r\n\r\n        self._session = tf.Session(graph=self._graph, config=self._config)\r\n    \r\n    def build(self):\r\n        with self._graph.as_default():\r\n\r\n            c_conf = tf.placeholder(tf.float32, [None, self._height, self._width, self._closeness_len], name='c')\r\n            p_conf = tf.placeholder(tf.float32, [None, self._height, self._width, self._period_len], name='p')\r\n            t_conf = tf.placeholder(tf.float32, [None, self._height, self._width, self._trend_len], name='t')\r\n\r\n            target = tf.placeholder(tf.float32, [None, self._height, self._width, 1], name='target')\r\n            \r\n            self._input['closeness_feature'] = c_conf.name\r\n            self._input['period_feature'] = p_conf.name\r\n            self._input['trend_feature'] = t_conf.name\r\n            self._input['target'] = target.name\r\n\r\n            # First convolution\r\n            h_c_1 = tf.layers.conv2d(inputs=c_conf, filters=self._num_conv_filters,\r\n                                     kernel_size=[self._kernel_size, self._kernel_size], padding='SAME', use_bias=True)\r\n            h_p_1 = tf.layers.conv2d(inputs=c_conf, filters=self._num_conv_filters,\r\n                                     kernel_size=[self._kernel_size, self._kernel_size], padding='SAME', use_bias=True)\r\n            h_t_1 = tf.layers.conv2d(inputs=c_conf, filters=self._num_conv_filters,\r\n                                     kernel_size=[self._kernel_size, self._kernel_size], padding='SAME', use_bias=True)\r\n\r\n            # First fusion\r\n            h_2 = tf.layers.conv2d(tf.concat([h_c_1, h_p_1, h_t_1], axis=-1),\r\n                                   filters=self._num_conv_filters, kernel_size=[self._kernel_size, self._kernel_size],\r\n                                   padding='SAME', use_bias=True)\r\n\r\n            # Stack more convolutions\r\n            middle_output = tf.layers.conv2d(h_2, filters=self._num_conv_filters,\r\n                                             kernel_size=[self._kernel_size, self._kernel_size],\r\n                                             padding='SAME', use_bias=True)\r\n            x = tf.layers.conv2d(middle_output, filters=self._num_conv_filters,\r\n                                 kernel_size=[self._kernel_size, self._kernel_size], padding='SAME', use_bias=True)\r\n\r\n            # external dims\r\n            if self._external_dim is not None and self._external_dim > 0:\r\n                external_input = tf.placeholder(tf.float32, [None, self._external_dim])\r\n                self._input['external_feature'] = external_input.name\r\n                external_dense = tf.layers.dense(inputs=external_input, units=10)\r\n                external_dense = tf.tile(tf.reshape(external_dense, [-1, 1, 1, 10]), [1, self._height, self._width, 1])\r\n                x = tf.concat([x, external_dense], axis=-1)\r\n\r\n            x = tf.layers.dense(x, units=1, name='prediction', activation=tf.nn.sigmoid)\r\n\r\n            loss = tf.sqrt(tf.reduce_mean(tf.square(x - target)), name='loss')\r\n            train_op = tf.train.AdamOptimizer(self._lr).minimize(loss)\r\n\r\n            self._output['prediction'] = x.name\r\n            self._output['loss'] = loss.name\r\n\r\n            self._op['train_op'] = train_op.name\r\n\r\n            self._variable_init = tf.global_variables_initializer()\r\n            self._saver = tf.train.Saver()\r\n\r\n        super(DeepST, self).build()\r\n\r\n    # Define your '_get_feed_dict function‘, map your input to the tf-model\r\n    def _get_feed_dict(self, closeness_feature=None, period_feature=None, trend_feature=None,\r\n                       target=None, external_feature=None):\r\n        '''\r\n        The method to get feet dict for tensorflow model.\r\n\r\n        Users may modify this method according to the format of input.\r\n\r\n        Args:\r\n            closeness_feature (np.ndarray or ``None``): The closeness history data.\r\n                If type is np.ndarray, its shape is [time_slot_num, height, width, closeness_len].\r\n            period_feature (np.ndarray or ``None``): The period history data.\r\n                If type is np.ndarray, its shape is [time_slot_num, height, width, period_len].\r\n            trend_feature (np.ndarray or ``None``): The trend history data.\r\n                If type is np.ndarray, its shape is [time_slot_num, height, width, trend_len].\r\n            target (np.ndarray or ``None``): The target value data.\r\n                If type is np.ndarray, its shape is [time_slot_num, height, width, 1].\r\n            external_feature (np.ndarray or ``None``): The external feature data.\r\n                If type is np.ndaaray, its shape is [time_slot_num, feature_num].\r\n        '''\r\n        feed_dict = {}\r\n        if target is not None:\r\n            feed_dict['target'] = target\r\n        if self._external_dim is not None and self._external_dim > 0:\r\n            feed_dict['external_feature'] = external_feature\r\n        if self._closeness_len is not None and self._closeness_len > 0:\r\n            feed_dict['closeness_feature'] = closeness_feature\r\n        if self._period_len is not None and self._period_len > 0:\r\n            feed_dict['period_feature'] = period_feature\r\n        if self._trend_len is not None and self._trend_len > 0:\r\n            feed_dict['trend_feature'] = trend_feature\r\n        return feed_dict\r\n"
  },
  {
    "path": "UCTB/model/GMAN.py",
    "content": "\nimport tensorflow as tf\nimport numpy as np\nimport random\n\nclass Graph():\n\tdef __init__(self, nx_G, is_directed, p, q):\n\t\tself.G = nx_G\n\t\tself.is_directed = is_directed\n\t\tself.p = p\n\t\tself.q = q\n\n\tdef node2vec_walk(self, walk_length, start_node):\n\t\t'''\n\t\tSimulate a random walk starting from start node.\n\t\t'''\n\t\tG = self.G\n\t\talias_nodes = self.alias_nodes\n\t\talias_edges = self.alias_edges\n\n\t\twalk = [start_node]\n\n\t\twhile len(walk) < walk_length:\n\t\t\tcur = walk[-1]\n\t\t\tcur_nbrs = sorted(G.neighbors(cur))\n\t\t\tif len(cur_nbrs) > 0:\n\t\t\t\tif len(walk) == 1:\n\t\t\t\t\twalk.append(cur_nbrs[alias_draw(alias_nodes[cur][0], alias_nodes[cur][1])])\n\t\t\t\telse:\n\t\t\t\t\tprev = walk[-2]\n\t\t\t\t\tnext = cur_nbrs[alias_draw(alias_edges[(prev, cur)][0],\n\t\t\t\t\t\talias_edges[(prev, cur)][1])]\n\t\t\t\t\twalk.append(next)\n\t\t\telse:\n\t\t\t\tbreak\n\n\t\treturn walk\n\n\tdef simulate_walks(self, num_walks, walk_length):\n\t\t'''\n\t\tRepeatedly simulate random walks from each node.\n\t\t'''\n\t\tG = self.G\n\t\twalks = []\n\t\tnodes = list(G.nodes())\n\t\tprint ('Walk iteration:')\n\t\tfor walk_iter in range(num_walks):\n\t\t\tprint (str(walk_iter+1), '/', str(num_walks))\n\t\t\trandom.shuffle(nodes)\n\t\t\tfor node in nodes:\n\t\t\t\twalks.append(self.node2vec_walk(walk_length=walk_length, start_node=node))\n\t\treturn walks\n\n\tdef get_alias_edge(self, src, dst):\n\t\t'''\n\t\tGet the alias edge setup lists for a given edge.\n\t\t'''\n\t\tG = self.G\n\t\tp = self.p\n\t\tq = self.q\n\t\tunnormalized_probs = []\n\t\tfor dst_nbr in sorted(G.neighbors(dst)):\n\t\t\tif dst_nbr == src:\n\t\t\t\tunnormalized_probs.append(G[dst][dst_nbr]['weight']/p)\n\t\t\telif G.has_edge(dst_nbr, src):\n\t\t\t\tunnormalized_probs.append(G[dst][dst_nbr]['weight'])\n\t\t\telse:\n\t\t\t\tunnormalized_probs.append(G[dst][dst_nbr]['weight']/q)\n\t\tnorm_const = sum(unnormalized_probs)\n\t\tnormalized_probs =  [float(u_prob)/norm_const for u_prob in unnormalized_probs]\n\n\t\treturn alias_setup(normalized_probs)\n\n\tdef preprocess_transition_probs(self):\n\t\t'''\n\t\tPreprocessing of transition probabilities for guiding the random walks.\n\t\t'''\n\t\tG = self.G\n\t\tis_directed = self.is_directed\n\t\talias_nodes = {}\n\t\tfor node in G.nodes():\n\t\t\tunnormalized_probs = [G[node][nbr]['weight'] for nbr in sorted(G.neighbors(node))]\n\t\t\tnorm_const = sum(unnormalized_probs)\n\t\t\tif norm_const == 0:\n\t\t\t\tprint(\"node:\",node)\n\t\t\t\tprint(\"unnormalized_probs:\",unnormalized_probs)\n\t\t\tnormalized_probs =  [float(u_prob)/norm_const for u_prob in unnormalized_probs]\n\t\t\talias_nodes[node] = alias_setup(normalized_probs)\n\n\t\talias_edges = {}\n\t\ttriads = {}\n\n\t\tif is_directed:\n\t\t\tfor edge in G.edges():\n\t\t\t\talias_edges[edge] = self.get_alias_edge(edge[0], edge[1])\n\t\telse:\n\t\t\tfor edge in G.edges():\n\t\t\t\talias_edges[edge] = self.get_alias_edge(edge[0], edge[1])\n\t\t\t\talias_edges[(edge[1], edge[0])] = self.get_alias_edge(edge[1], edge[0])\n\n\t\tself.alias_nodes = alias_nodes\n\t\tself.alias_edges = alias_edges\n\n\t\treturn\n\ndef alias_setup(probs):\n\t'''\n\tCompute utility lists for non-uniform sampling from discrete distributions.\n\tRefer to https://hips.seas.harvard.edu/blog/2013/03/03/the-alias-method-efficient-sampling-with-many-discrete-outcomes/\n\tfor details\n\t'''\n\tK = len(probs)\n\tq = np.zeros(K)\n\tJ = np.zeros(K, dtype=np.int)\n\n\tsmaller = []\n\tlarger = []\n\tfor kk, prob in enumerate(probs):\n\t\tq[kk] = K*prob\n\t\tif q[kk] < 1.0:\n\t\t\tsmaller.append(kk)\n\t\telse:\n\t\t\tlarger.append(kk)\n\n\twhile len(smaller) > 0 and len(larger) > 0:\n\t\tsmall = smaller.pop()\n\t\tlarge = larger.pop()\n\n\t\tJ[small] = large\n\t\tq[large] = q[large] + q[small] - 1.0\n\t\tif q[large] < 1.0:\n\t\t\tsmaller.append(large)\n\t\telse:\n\t\t\tlarger.append(large)\n\n\treturn J, q\n\ndef alias_draw(J, q):\n\t'''\n\tDraw sample from a non-uniform discrete distribution using alias sampling.\n\t'''\n\tK = len(J)\n\n\tkk = int(np.floor(np.random.rand()*K))\n\tif np.random.rand() < q[kk]:\n\t\treturn kk\n\telse:\n\t\treturn J[kk]\n\n\ndef conv2d(x, output_dims, kernel_size, stride = [1, 1],\n\t\t   padding = 'SAME', use_bias = True, activation = tf.nn.relu,\n\t\t   bn = False, bn_decay = None, is_training = None):\n\tinput_dims = x.get_shape()[-1].value\n\tkernel_shape = kernel_size + [input_dims, output_dims]\n\tkernel = tf.Variable(\n\t\ttf.glorot_uniform_initializer()(shape = kernel_shape),\n\t\tdtype = tf.float32, trainable = True, name = 'kernel')\n\tx = tf.nn.conv2d(x, kernel, [1] + stride + [1], padding = padding)\n\tif use_bias:\n\t\tbias = tf.Variable(\n\t\t\ttf.zeros_initializer()(shape = [output_dims]),\n\t\t\tdtype = tf.float32, trainable = True, name = 'bias')\n\t\tx = tf.nn.bias_add(x, bias)\n\tif activation is not None:\n\t\tif bn:\n\t\t\tx = batch_norm(x, is_training = is_training, bn_decay = bn_decay)\n\t\tx = activation(x)\n\treturn x\n\ndef batch_norm(x, is_training, bn_decay):\n\tinput_dims = x.get_shape()[-1].value\n\tmoment_dims = list(range(len(x.get_shape()) - 1))\n\tbeta = tf.Variable(\n\t\ttf.zeros_initializer()(shape = [input_dims]),\n\t\tdtype = tf.float32, trainable = True, name = 'beta')\n\tgamma = tf.Variable(\n\t\ttf.ones_initializer()(shape = [input_dims]),\n\t\tdtype = tf.float32, trainable = True, name = 'gamma')\n\tbatch_mean, batch_var = tf.nn.moments(x, moment_dims, name='moments')\n\n\tdecay = bn_decay if bn_decay is not None else 0.9\n\tema = tf.train.ExponentialMovingAverage(decay = decay)\n\t# Operator that maintains moving averages of variables.\n\tema_apply_op = tf.cond(\n\t\tis_training,\n\t\tlambda: ema.apply([batch_mean, batch_var]),\n\t\tlambda: tf.no_op())\n\t# Update moving average and return current batch's avg and var.\n\tdef mean_var_with_update():\n\t\twith tf.control_dependencies([ema_apply_op]):\n\t\t\treturn tf.identity(batch_mean), tf.identity(batch_var)\n\t# ema.average returns the Variable holding the average of var.\n\tmean, var = tf.cond(\n\t\tis_training,\n\t\tmean_var_with_update,\n\t\tlambda: (ema.average(batch_mean), ema.average(batch_var)))\n\tx = tf.nn.batch_normalization(x, mean, var, beta, gamma, 1e-3)\n\treturn x\n\ndef dropout(x, drop, is_training):\n\tx = tf.cond(\n\t\tis_training,\n\t\tlambda: tf.nn.dropout(x, rate = drop),\n\t\tlambda: x)\n\treturn x\n\n\ndef placeholder(P, Q, N):\n\tX = tf.compat.v1.placeholder(shape=(None, P, N), dtype=tf.float32)\n\tTE = tf.compat.v1.placeholder(shape=(None, P + Q, 2), dtype=tf.int32)\n\tlabel = tf.compat.v1.placeholder(shape=(None, Q, N), dtype=tf.float32)\n\tis_training = tf.compat.v1.placeholder(shape=(), dtype=tf.bool)\n\treturn X, TE, label, is_training\n\n\ndef FC(x, units, activations, bn, bn_decay, is_training, use_bias=True):\n\tif isinstance(units, int):\n\t\tunits = [units]\n\t\tactivations = [activations]\n\telif isinstance(units, tuple):\n\t\tunits = list(units)\n\t\tactivations = list(activations)\n\tassert type(units) == list\n\tfor num_unit, activation in zip(units, activations):\n\t\tx = conv2d(\n\t\t\tx, output_dims=num_unit, kernel_size=[1, 1], stride=[1, 1],\n\t\t\tpadding='VALID', use_bias=use_bias, activation=activation,\n\t\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\treturn x\n\n\ndef STEmbedding(SE, TE, T, D, bn, bn_decay, is_training):\n\t'''\n\tspatio-temporal embedding\n\n\tSE:\t [N, D]\n\tTE:\t [batch_size, P + Q, 2] (dayofweek, timeofday)\n\tT:\t  num of time steps in one day\n\tD:\t  output dims\n\tretrun: [batch_size, P + Q, N, D]\n\t'''\n\t# spatial embedding\n\tSE = tf.expand_dims(tf.expand_dims(SE, axis=0), axis=0)\n\tSE = FC(\n\t\tSE, units=[D, D], activations=[tf.nn.relu, None],\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\t# temporal embedding\n\tdayofweek = tf.one_hot(TE[..., 0], depth=7)\n\ttimeofday = tf.one_hot(TE[..., 1], depth=T)\n\tTE = tf.concat((dayofweek, timeofday), axis=-1)\n\tTE = tf.expand_dims(TE, axis=2)\n\tTE = FC(\n\t\tTE, units=[D, D], activations=[tf.nn.relu, None],\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\treturn tf.add(SE, TE)\n\n\ndef spatialAttention(X, STE, K, d, bn, bn_decay, is_training):\n\t'''\n\tspatial attention mechanism\n\n\tX:\t  [batch_size, num_step, N, D]\n\tSTE:\t[batch_size, num_step, N, D]\n\tK:\t  number of attention heads\n\td:\t  dimension of each attention outputs\n\treturn: [batch_size, num_step, N, D]\n\t'''\n\tD = K * d\n\tX = tf.concat((X, STE), axis=-1)\n\t# [batch_size, num_step, N, K * d]\n\tquery = FC(\n\t\tX, units=D, activations=tf.nn.relu,\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\tkey = FC(\n\t\tX, units=D, activations=tf.nn.relu,\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\tvalue = FC(\n\t\tX, units=D, activations=tf.nn.relu,\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\t# [K * batch_size, num_step, N, d]\n\tquery = tf.concat(tf.split(query, K, axis=-1), axis=0)\n\tkey = tf.concat(tf.split(key, K, axis=-1), axis=0)\n\tvalue = tf.concat(tf.split(value, K, axis=-1), axis=0)\n\t# [K * batch_size, num_step, N, N]\n\tattention = tf.matmul(query, key, transpose_b=True)\n\tattention /= (d ** 0.5)\n\tattention = tf.nn.softmax(attention, axis=-1)\n\t# [batch_size, num_step, N, D]\n\tX = tf.matmul(attention, value)\n\tX = tf.concat(tf.split(X, K, axis=0), axis=-1)\n\tX = FC(\n\t\tX, units=[D, D], activations=[tf.nn.relu, None],\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\treturn X\n\n\ndef temporalAttention(X, STE, K, d, bn, bn_decay, is_training, mask=True):\n\t'''\n\ttemporal attention mechanism\n\n\tX:\t  [batch_size, num_step, N, D]\n\tSTE:\t[batch_size, num_step, N, D]\n\tK:\t  number of attention heads\n\td:\t  dimension of each attention outputs\n\treturn: [batch_size, num_step, N, D]\n\t'''\n\tD = K * d\n\tX = tf.concat((X, STE), axis=-1)\n\t# [batch_size, num_step, N, K * d]\n\tquery = FC(\n\t\tX, units=D, activations=tf.nn.relu,\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\tkey = FC(\n\t\tX, units=D, activations=tf.nn.relu,\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\tvalue = FC(\n\t\tX, units=D, activations=tf.nn.relu,\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\t# [K * batch_size, num_step, N, d]\n\tquery = tf.concat(tf.split(query, K, axis=-1), axis=0)\n\tkey = tf.concat(tf.split(key, K, axis=-1), axis=0)\n\tvalue = tf.concat(tf.split(value, K, axis=-1), axis=0)\n\t# query: [K * batch_size, N, num_step, d]\n\t# key:   [K * batch_size, N, d, num_step]\n\t# value: [K * batch_size, N, num_step, d]\n\tquery = tf.transpose(query, perm=(0, 2, 1, 3))\n\tkey = tf.transpose(key, perm=(0, 2, 3, 1))\n\tvalue = tf.transpose(value, perm=(0, 2, 1, 3))\n\t# [K * batch_size, N, num_step, num_step]\n\tattention = tf.matmul(query, key)\n\tattention /= (d ** 0.5)\n\t# mask attention score\n\tif mask:\n\t\tbatch_size = tf.shape(X)[0]\n\t\tnum_step = X.get_shape()[1].value\n\t\tN = X.get_shape()[2].value\n\t\tmask = tf.ones(shape=(num_step, num_step))\n\t\tmask = tf.linalg.LinearOperatorLowerTriangular(mask).to_dense()\n\t\tmask = tf.expand_dims(tf.expand_dims(mask, axis=0), axis=0)\n\t\tmask = tf.tile(mask, multiples=(K * batch_size, N, 1, 1))\n\t\tmask = tf.cast(mask, dtype=tf.bool)\n\t\tattention = tf.compat.v2.where(\n\t\t\tcondition=mask, x=attention, y=-2 ** 15 + 1)\n\t# softmax\n\tattention = tf.nn.softmax(attention, axis=-1)\n\t# [batch_size, num_step, N, D]\n\tX = tf.matmul(attention, value)\n\tX = tf.transpose(X, perm=(0, 2, 1, 3))\n\tX = tf.concat(tf.split(X, K, axis=0), axis=-1)\n\tX = FC(\n\t\tX, units=[D, D], activations=[tf.nn.relu, None],\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\treturn X\n\n\ndef gatedFusion(HS, HT, D, bn, bn_decay, is_training):\n\t'''\n\tgated fusion\n\n\tHS:\t [batch_size, num_step, N, D]\n\tHT:\t [batch_size, num_step, N, D]\n\tD:\t  output dims\n\treturn: [batch_size, num_step, N, D]\n\t'''\n\tXS = FC(\n\t\tHS, units=D, activations=None,\n\t\tbn=bn, bn_decay=bn_decay,\n\t\tis_training=is_training, use_bias=False)\n\tXT = FC(\n\t\tHT, units=D, activations=None,\n\t\tbn=bn, bn_decay=bn_decay,\n\t\tis_training=is_training, use_bias=True)\n\tz = tf.nn.sigmoid(tf.add(XS, XT))\n\tH = tf.add(tf.multiply(z, HS), tf.multiply(1 - z, HT))\n\tH = FC(\n\t\tH, units=[D, D], activations=[tf.nn.relu, None],\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\treturn H\n\n\ndef STAttBlock(X, STE, K, d, bn, bn_decay, is_training, mask=False):\n\tHS = spatialAttention(X, STE, K, d, bn, bn_decay, is_training)\n\tHT = temporalAttention(X, STE, K, d, bn, bn_decay, is_training, mask=mask)\n\tH = gatedFusion(HS, HT, K * d, bn, bn_decay, is_training)\n\treturn tf.add(X, H)\n\n\ndef transformAttention(X, STE_P, STE_Q, K, d, bn, bn_decay, is_training):\n\t'''\n\ttransform attention mechanism\n\t\n\tX:\t  [batch_size, P, N, D]\n\tSTE_P:  [batch_size, P, N, D]\n\tSTE_Q:  [batch_size, Q, N, D]\n\tK:\t  number of attention heads\n\td:\t  dimension of each attention outputs\n\treturn: [batch_size, Q, N, D]\n\t'''\n\tD = K * d\n\t# query: [batch_size, Q, N, K * d]\n\t# key:   [batch_size, P, N, K * d]\n\t# value: [batch_size, P, N, K * d]\n\tquery = FC(\n\t\tSTE_Q, units=D, activations=tf.nn.relu,\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\tkey = FC(\n\t\tSTE_P, units=D, activations=tf.nn.relu,\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\tvalue = FC(\n\t\tX, units=D, activations=tf.nn.relu,\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\t# query: [K * batch_size, Q, N, d]\n\t# key:   [K * batch_size, P, N, d]\n\t# value: [K * batch_size, P, N, d]\n\tquery = tf.concat(tf.split(query, K, axis=-1), axis=0)\n\tkey = tf.concat(tf.split(key, K, axis=-1), axis=0)\n\tvalue = tf.concat(tf.split(value, K, axis=-1), axis=0)\n\t# query: [K * batch_size, N, Q, d]\n\t# key:   [K * batch_size, N, d, P]\n\t# value: [K * batch_size, N, P, d]\n\tquery = tf.transpose(query, perm=(0, 2, 1, 3))\n\tkey = tf.transpose(key, perm=(0, 2, 3, 1))\n\tvalue = tf.transpose(value, perm=(0, 2, 1, 3))\n\t# [K * batch_size, N, Q, P]\n\tattention = tf.matmul(query, key)\n\tattention /= (d ** 0.5)\n\tattention = tf.nn.softmax(attention, axis=-1)\n\t# [batch_size, Q, N, D]\n\tX = tf.matmul(attention, value)\n\tX = tf.transpose(X, perm=(0, 2, 1, 3))\n\tX = tf.concat(tf.split(X, K, axis=0), axis=-1)\n\tX = FC(\n\t\tX, units=[D, D], activations=[tf.nn.relu, None],\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\treturn X\n\n\ndef GMAN(X, TE, SE, P, Q, T, L, K, d, bn, bn_decay, is_training):\n\t\"\"\"\n\tReferences:\n        - `Gman: A graph multi-attention network for traffic prediction.\n          <https://ojs.aaai.org/index.php/AAAI/article/view/5477>`_.\n        - `A Tensorflow implementation of the GMAN model  (Zhengchuanpan)\n          <https://github.com/zhengchuanpan/GMAN>`_.\n\n    Args:\n\t\tP(int): Number of history steps.\n\t\tQ(int): Number of prediction steps.\n\t\tT(int): Number of steps which one day is divided into.\n\t\tL(int): Number of STAtt blocks in the encoder/decoder.\n\t\tK(int): Number of attention heads.\n\t\td(int): Number of dimension of each attention head outputs.\n        X(tf.Tensor): Input traffic data with shape [batch_size, ...]\n        TE(tf.Tensor): Temporal embedding [batch_size, ...]\n        SE(tf.Tensor): Spatial embedding [batch_size, ...]\n\t\tbn(bool): Whether to do batch normalization.\n\t\tis_training(bool): Whether to train.\n    \"\"\"\n\tD = K * d\n\t# input\n\tX = tf.expand_dims(X, axis=-1)\n\tX = FC(\n\t\tX, units=[D, D], activations=[tf.nn.relu, None],\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\t# STE\n\tSTE = STEmbedding(SE, TE, T, D, bn, bn_decay, is_training)\n\tSTE_P = STE[:, : P]\n\tSTE_Q = STE[:, P:]\n\t# encoder\n\tfor _ in range(L):\n\t\tX = STAttBlock(X, STE_P, K, d, bn, bn_decay, is_training)\n\t# transAtt\n\tX = transformAttention(\n\t\tX, STE_P, STE_Q, K, d, bn, bn_decay, is_training)\n\t# decoder\n\tfor _ in range(L):\n\t\tX = STAttBlock(X, STE_Q, K, d, bn, bn_decay, is_training)\n\t# output\n\tX = FC(\n\t\tX, units=[D, 1], activations=[tf.nn.relu, None],\n\t\tbn=bn, bn_decay=bn_decay, is_training=is_training)\n\treturn tf.squeeze(X, axis=3)\n\n"
  },
  {
    "path": "UCTB/model/GeoMAN.py",
    "content": "import tensorflow as tf\nfrom tensorflow.contrib.framework import nest\nfrom ..model_unit import BaseModel\n\n\nclass GeoMAN(BaseModel):\n    \"\"\"Multi-level Attention Networks for Geo-sensory Time Series Prediction (GeoMAN)\n\n            GeoMAN consists of two major parts: 1) A multi-level attention mechanism (including both local and global\n            spatial attentions in encoder and temporal attention in decoder) to model the dynamic spatio-temporal\n            dependencies; 2) A general fusion module to incorporate the external factors from different domains (e.g.,\n            meteorology, time of day and land use).\n\n            References:\n                - `GeoMAN: Multi-level Attention Networks for Geo-sensory Time Series Prediction (Liang Yuxuan, et al., 2018)\n                  <https://www.ijcai.org/proceedings/2018/0476.pdf>`_.\n                - `An easy implement of GeoMAN using TensorFlow (yoshall & CastleLiang)\n                  <https://github.com/yoshall/GeoMAN>`_.\n\n            Args:\n                total_sensers (int): The number of total sensors used in global attention mechanism.\n                input_dim (int): The number of dimensions of the target sensor's input.\n                external_dim (int): The number of dimensions of the external features.\n                output_dim (int): The number of dimensions of the target sensor's output.\n                input_steps (int): The length of historical input data, a.k.a, input timesteps.\n                output_steps (int): The number of steps that need prediction by one piece of history data, a.k.a, output\n                    timesteps. Have to be 1 now.\n                n_stacked_layers (int): The number of LSTM layers stacked in both encoder and decoder (These two are the\n                    same). Default: 2\n                n_encoder_hidden_units (int): The number of hidden units in each layer of encoder. Default: 128\n                n_decoder_hidden_units (int): The number of hidden units in each layer of decoder. Default: 128\n                dropout_rate (float): Dropout rate of LSTM layers in both encoder and decoder. Default: 0.3\n                lr (float): Learning rate. Default: 0.001\n                gc_rate (float): A clipping ratio for all the gradients. This operation normalizes all gradients so that\n                    their L2-norms are less than or equal to ``gc_rate``. Default: 2.5\n                code_version (str): Current version of this model code. Default: 'GeoMAN-QuickStart'\n                model_dir (str): The directory to store model files. Default:'model_dir'\n                gpu_device (str): To specify the GPU to use. Default: '0'\n                **kwargs (dict): Reserved for future use. May be used to pass parameters to class ``BaseModel``.\n            \"\"\"\n    def __init__(self,\n                 total_sensers,\n                 input_dim,\n                 external_dim,\n                 output_dim,\n                 input_steps,\n                 output_steps,\n                 n_stacked_layers=2,\n                 n_encoder_hidden_units=128,\n                 n_decoder_hidden_units=128,\n                 dropout_rate=0.3,\n                 lr=0.001,\n                 gc_rate=2.5,\n                 code_version='GeoMAN-QuickStart',\n                 model_dir='model_dir',\n                 gpu_device='0',\n                 **kwargs):\n\n        super(GeoMAN, self).__init__(code_version=code_version, model_dir=model_dir, gpu_device=gpu_device)\n\n        # Architecture\n        self._n_stacked_layers = n_stacked_layers\n        self._n_encoder_hidden_units = n_encoder_hidden_units\n        self._n_decoder_hidden_units = n_decoder_hidden_units\n        self._n_output_decoder = output_dim  # n_output_decoder\n\n        self._n_steps_encoder = input_steps  # encoder_steps\n        self._n_steps_decoder = output_steps  # decoder_steps\n        self._n_input_encoder = input_dim  # n_input_encoder\n        self._n_sensers = total_sensers  # n_sensers\n        self._n_external_input = external_dim  # external_dim\n\n        # Hyperparameters\n        self._dropout_rate = dropout_rate\n        self._lr = lr\n        self._gc_rate = gc_rate\n\n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            with tf.variable_scope('inputs'):\n                local_features = tf.placeholder(tf.float32, shape=[None, self._n_steps_encoder, self._n_input_encoder],\n                                                name='local_features')\n                global_features = tf.placeholder(tf.float32, shape=[None, self._n_steps_encoder, self._n_sensers],\n                                                 name='global_features')\n                external_features = tf.placeholder(tf.float32,\n                                                   shape=[None, self._n_steps_decoder, self._n_external_input],\n                                                   name='external_features')\n                local_attn_states = tf.placeholder(tf.float32,\n                                                   shape=[None, self._n_input_encoder, self._n_steps_encoder],\n                                                   name='local_attn_states')\n                global_attn_states = tf.placeholder(tf.float32, shape=[None, self._n_sensers, self._n_input_encoder,\n                                                                       self._n_steps_encoder],\n                                                    name='global_attn_states')\n            with tf.variable_scope('ground_truth'):\n                targets = tf.placeholder(tf.float32, [None, self._n_steps_decoder, self._n_output_decoder])\n\n            self._input['local_features'] = local_features.name\n            self._input['global_features'] = global_features.name\n            self._input['external_features'] = external_features.name\n            self._input['local_attn_states'] = local_attn_states.name\n            self._input['global_attn_states'] = global_attn_states.name\n            self._input['targets'] = targets.name\n\n            predict_layer = tf.keras.layers.Dense(units=self._n_output_decoder,\n                                                  kernel_initializer=tf.truncated_normal_initializer,\n                                                  bias_initializer=tf.constant_initializer(0.),\n                                                  use_bias=True)\n\n            def _build_cells(n_hidden_units):\n                cells = []\n                for i in range(self._n_stacked_layers):\n                    with tf.variable_scope(f'LSTM_{i}'):\n                        cell = tf.contrib.rnn.BasicLSTMCell(n_hidden_units,\n                                                            forget_bias=1.0,\n                                                            state_is_tuple=True)\n                        cell = tf.nn.rnn_cell.DropoutWrapper(cell, output_keep_prob=1.0 - self._dropout_rate)\n                        cells.append(cell)\n                encoder_cell = tf.contrib.rnn.MultiRNNCell(cells)\n                return encoder_cell\n\n            def _loop_function(prev):\n                \"\"\"loop function used in the decoder to generate the next input\"\"\"\n                return predict_layer(prev)\n\n            def _get_MSE_loss(y_true, y_pred):\n                return tf.reduce_mean(tf.pow(y_true - y_pred, 2), name='MSE_loss')\n\n            def _get_l2reg_loss():\n                # l2 loss\n                reg_loss = 0\n                for tf_var in tf.trainable_variables():\n                    if 'kernel:' in tf_var.name or 'bias:' in tf_var.name:\n                        reg_loss += tf.reduce_mean(tf.nn.l2_loss(tf_var))\n                return 0.001 * reg_loss\n\n            def _spatial_attention(local_features,  # x and X\n                                   global_features,\n                                   local_attention_states,\n                                   global_attention_states,\n                                   encoder_cells,  # to acquire h_{t-1}, s_{t-1}\n                                   ):\n                batch_size = tf.shape(local_features[0])[0]\n                output_size = encoder_cells.output_size\n                with tf.variable_scope('spatial_attention'):\n                    with tf.variable_scope('local_spatial_attn'):\n                        local_attn_length = local_attention_states.get_shape()[1].value  # n_input_encoder\n                        local_attn_size = local_attention_states.get_shape()[2].value  # n_steps_encoder\n                        local_attn = tf.zeros([batch_size, local_attn_length])\n\n                        #  Add local features in attention\n                        x_ik = tf.reshape(local_attention_states,\n                                          [-1, local_attn_length, 1, local_attn_size])  # features\n                        Ul = tf.get_variable('spati_atten_Ul', [1, 1, local_attn_size, local_attn_size])\n                        Ul_x = tf.nn.conv2d(x_ik, Ul, [1, 1, 1, 1], 'SAME')  # U_l * x^{i,k}\n                        vl = tf.get_variable('spati_atten_vl', [local_attn_size])  # v_l\n\n                        def _local_spatial_attention(query):\n                            # If the query is a tuple (when stacked RNN/LSTM), flatten it\n                            if hasattr(query, \"__iter__\"):\n                                query_list = nest.flatten(query)\n                                for q in query_list:\n                                    ndims = q.get_shape().ndims\n                                    if ndims:\n                                        assert ndims == 2\n                                query = tf.concat(query_list, 1)\n                            with tf.variable_scope('local_spatial_attn_Wl'):\n                                h_s = query\n                                Wl_hs_bl = tf.keras.layers.Dense(units=local_attn_size, use_bias=True)(h_s)\n                                Wl_hs_bl = tf.reshape(Wl_hs_bl, [-1, 1, 1, local_attn_size])\n                                score = tf.reduce_sum(vl * tf.nn.tanh(Wl_hs_bl + Ul_x),\n                                                      [2, 3])  # ! Ux is a 4 dims matrix, have to use reduce_sum here\n                                attention_weights = tf.nn.softmax(score)\n                            return attention_weights\n\n                    with tf.variable_scope('global_spatial_attn'):\n                        global_attn_length = global_attention_states.get_shape()[1].value  # n_sensor\n                        global_n_input = global_attention_states.get_shape()[2].value  # n_input_dim\n                        global_attn_size = global_attention_states.get_shape()[3].value  # n_input_dim\n                        global_attn = tf.zeros([batch_size, global_attn_length])\n\n                        # Add global features in attention\n                        Xl = tf.reshape(global_attention_states,\n                                        [-1, global_attn_length, global_n_input, global_attn_size])\n                        Wg_ug = tf.get_variable('spati_atten_Wg_ug',\n                                                [1, global_n_input, global_attn_size, global_attn_size])\n                        Wg_Xl_ug = tf.nn.conv2d(Xl, Wg_ug, [1, 1, 1, 1], 'SAME')\n                        vg = tf.get_variable('spati_atten_vg', [local_attn_size])\n\n                        # TODO: add U_g * y^l here, where y^l is the first column of local inputs.\n\n                        def _global_spatial_attention(query):\n                            if hasattr(query, \"__iter__\"):\n                                query_list = nest.flatten(query)\n                                for q in query_list:  # Check that ndims == 2 if specified.\n                                    ndims = q.get_shape().ndims\n                                    if ndims:\n                                        assert ndims == 2\n                                query = tf.concat(query_list, 1)\n                            with tf.variable_scope('global_spatial_attn_Wl'):\n                                h_s = query\n                                Wg_hs_bg = tf.keras.layers.Dense(units=global_attn_size, use_bias=True)(h_s)\n                                Wg_hs_bg = tf.reshape(Wg_hs_bg, [-1, 1, 1, global_attn_size])\n                                score = tf.reduce_sum(vg * tf.nn.tanh(Wg_hs_bg + Wg_Xl_ug), [2, 3])\n                                attention_weights = tf.nn.softmax(score)\n                                # Sometimes it's not easy to find a measurement to denote similarity between sensors,\n                                # here we omit such prior knowledge in eq.[4].\n                                # You can use \"a = nn_ops.softmax((1-lambda)*s + lambda*sim)\" to encode similarity info,\n                                # where:\n                                #     sim: a vector with length n_sensors, describing the sim between the target sensor and the others\n                                #     lambda: a trade-off.\n                                # attention_weights = tf.softmax((1-self.sm_rate)*score+self.sm_rate*self.similarity_graph)\n                            return attention_weights\n\n                    # Init\n                    zeros = [tf.zeros([batch_size, output_size]) for i in range(2)]\n                    initial_state = [zeros for _ in range(len(encoder_cells._cells))]\n                    state = initial_state\n\n                    # For each timestep\n                    outputs = []\n                    attn_weights = []\n                    for i, (local_input, global_input) in enumerate(zip(local_features, global_features)):\n                        if i > 0: tf.get_variable_scope().reuse_variables()\n\n                        local_context_vector = local_attn * local_input\n                        global_context_vector = global_attn * global_input\n                        x_t = tf.concat([local_context_vector, global_context_vector], axis=1)\n                        encoder_output, state = encoder_cells(x_t, state)  # Update states\n\n                        with tf.variable_scope('local_spatial_attn'):\n                            local_attn = _local_spatial_attention(state)\n                        with tf.variable_scope('global_spatial_attn'):\n                            global_attn = _global_spatial_attention(state)\n                        attn_weights.append((local_attn, global_attn))\n                        outputs.append(encoder_output)\n\n                return outputs, state, attn_weights\n\n            def _temporal_attention(decoder_inputs,\n                                    external_features,\n                                    inital_states,  # the first time, the output of encoder\n                                    attention_states,  # h_o\n                                    decoder_cells):\n                batch_size = tf.shape(decoder_inputs[0])[0]\n                output_size = decoder_cells.output_size\n                input_size = decoder_inputs[0].get_shape().with_rank(2)[1]  # ?\n                state = inital_states\n                with tf.variable_scope('temperal_attention'):\n                    attn_length = attention_states.get_shape()[1].value\n                    attn_size = attention_states.get_shape()[2].value\n\n                    h_o = tf.reshape(attention_states, [-1, attn_length, 1, attn_size])\n                    W_d = tf.get_variable('temperal_attn_Wd', [1, 1, attn_size, attn_size])\n                    W_h = tf.nn.conv2d(h_o, W_d, [1, 1, 1, 1], 'SAME')\n                    v_d = tf.get_variable('temperal_attn_vd', [attn_size])\n\n                    def _attention(query):\n                        if hasattr(query, \"__iter__\"):\n                            query_list = nest.flatten(query)\n                            for q in query_list:  # Check that ndims == 2 if specified.\n                                ndims = q.get_shape().ndims\n                                if ndims:\n                                    assert ndims == 2\n                            query = tf.concat(query_list, 1)\n                        with tf.variable_scope('attention'):\n                            d_s = query\n                            W_ds_b = tf.keras.layers.Dense(units=attn_size, use_bias=True)(d_s)\n                            W_ds_b = tf.reshape(W_ds_b, [-1, 1, 1, attn_size])\n                            score = tf.reduce_sum(v_d * tf.nn.tanh(W_ds_b + W_h), [2, 3])\n                            attention_weights = tf.nn.softmax(score)\n                            context_vector = tf.reduce_sum(\n                                tf.reshape(attention_weights, [-1, attn_length, 1, 1]) * h_o, [1, 2])\n                            context_vector = tf.reshape(context_vector, [-1, attn_size])\n                        return context_vector\n\n                    # Init\n                    inital_attn = tf.zeros([batch_size, output_size])\n                    attn = inital_attn\n                    outputs = []\n\n                    prev_decoder_output = None  # d_{t-1}\n                    for i, (decoder_input, external_input) in enumerate(zip(decoder_inputs, external_features)):\n                        if i > 0: tf.get_variable_scope().reuse_variables()\n                        if prev_decoder_output is not None and _loop_function is not None:\n                            with tf.variable_scope('loop_function', reuse=True):\n                                decoder_input = _loop_function(prev_decoder_output)\n                        x = tf.concat([decoder_input, external_input, attn], axis=1)\n                        x = tf.keras.layers.Dense(units=input_size, use_bias=True)(x)\n                        decoder_output, state = decoder_cells(x, state)\n                        # Update attention weights\n                        attn = _attention(state)\n                        # Attention output projection\n                        with tf.variable_scope(\"attn_output_projection\"):\n                            x = tf.concat([decoder_output, attn], axis=1)\n                            output = tf.keras.layers.Dense(units=output_size, use_bias=True)(x)\n                        outputs.append(output)\n                        prev_decoder_output = output\n                return outputs, state\n\n            # Handle data\n            local_features, global_features, external_features, targets, decoder_inputs = input_transform(\n                local_features, global_features, external_features, targets)\n\n            with tf.variable_scope('GeoMAN'):\n                with tf.variable_scope('encoder'):\n                    encoder_cells = _build_cells(self._n_encoder_hidden_units)\n                    encoder_outputs, encoder_state, attn_weights = _spatial_attention(local_features,\n                                                                                      global_features,\n                                                                                      local_attn_states,\n                                                                                      global_attn_states,\n                                                                                      encoder_cells)\n                    top_states = [tf.reshape(e, [-1, 1, encoder_cells.output_size]) for e in encoder_outputs]\n                    attention_states = tf.concat(top_states, 1)\n\n                with tf.variable_scope('decoder'):\n                    decoder_cells = _build_cells(self._n_decoder_hidden_units)\n                    decoder_outputs, states = _temporal_attention(decoder_inputs,\n                                                                  external_features,\n                                                                  encoder_state,\n                                                                  attention_states,\n                                                                  decoder_cells)\n\n                with tf.variable_scope('prediction'):\n                    predictions = []\n                    for decoder_output in decoder_outputs:\n                        predictions.append(predict_layer(decoder_output))\n                    predictions = tf.stack(predictions, axis=1, name='predictions')\n\n                with tf.variable_scope('loss'):\n                    targets = tf.stack(targets, axis=1, name='targets')\n                    loss = tf.add(_get_MSE_loss(targets, predictions), _get_l2reg_loss(), name='loss')\n\n                with tf.variable_scope('train_op'):\n                    global_step = tf.train.get_or_create_global_step()\n                    optimizer = tf.train.AdamOptimizer(self._lr)\n                    gradients, variables = zip(*optimizer.compute_gradients(loss))\n                    gradients, _ = tf.clip_by_global_norm(gradients, self._gc_rate)  # clip norm\n                    train_op = optimizer.apply_gradients(zip(gradients, variables), global_step)\n\n                # record output\n                self._output['prediction'] = predictions.name\n                self._output['loss'] = loss.name\n                # record op\n                self._op['train_op'] = train_op.name\n\n        super(GeoMAN, self).build(init_vars=init_vars, max_to_keep=5)\n\n    def _get_feed_dict(self,\n                       local_features,\n                       global_features,\n                       local_attn_states,\n                       global_attn_states,\n                       external_features,\n                       targets):\n        \"\"\"The method to get feet dict for tensorflow model.\n\n        Users may modify this method according to the format of input.\n\n        Args:\n            local_features (np.ndarray): All the time series generated by the target sensor i, including one target\n                series and other feature series, with shape `(batch, input_steps, input_dim)`.\n            global_features (np.ndarray): Target series generated by all the sensors, with shape `(batch, input_steps,\n                total_sensors)`.\n            local_attn_states (np.ndarray): Equals to ``local_features`` swapped ``input_steps`` and ``input_dim`` axis,\n                with shape `(batch, input_dim, input_steps)`.\n            global_attn_states (np.ndarray): All time series generated by all sensors, with shape `(batch,\n                total_sensors, input_dim, input_steps)`.\n            external_features (np.ndarray): Fused external factors, e.g., temporal factors: meteorology and spatial\n                factors: POIs density, with shape `(batch, output_steps, external_dim)`. All features have to be\n                time series.\n            targets (np.ndarray): Target sensor's labels, with shape `(batch, output_steps, output_dim)`.\n        \"\"\"\n        feed_dict = {'local_features': local_features, 'global_features': global_features,\n                     'local_attn_states': local_attn_states, 'global_attn_states': global_attn_states,\n                     'external_features': external_features, 'targets': targets}\n        return feed_dict\n\n\ndef input_transform(local_features,\n                    global_features,\n                    external_features,\n                    targets):\n    \"\"\"Split the model's inputs from matrices to lists on timesteps axis.\"\"\"\n    local_features = split_timesteps(local_features)\n    global_features = split_timesteps(global_features)\n    external_features = split_timesteps(external_features)\n    targets = split_timesteps(targets)\n    decoder_inputs = [tf.zeros_like(targets[0], dtype=tf.float32)] + targets[:-1]  # useless when loop func is employed\n    return local_features, global_features, external_features, targets, decoder_inputs\n\n\ndef split_timesteps(inputs):\n    \"\"\"Split the input matrix from (batch, timesteps, input_dim) to a step list ([[batch, input_dim], ..., ]).\"\"\"\n    timesteps = inputs.get_shape()[1].value\n    feature_dims = inputs.get_shape()[2].value\n    inputs = tf.transpose(inputs, [1, 0, 2])\n    inputs = tf.reshape(inputs, [-1, feature_dims])\n    inputs = tf.split(inputs, timesteps, 0)\n    return inputs\n\n\n\n"
  },
  {
    "path": "UCTB/model/GraphWaveNet.py",
    "content": "import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nclass nconv(nn.Module):\n    def __init__(self):\n        super(nconv,self).__init__()\n\n    def forward(self,x, A):\n        x = torch.einsum('ncvl,vw->ncwl',(x,A))\n        return x.contiguous()\n\nclass linear(nn.Module):\n    def __init__(self,c_in,c_out):\n        super(linear,self).__init__()\n        self.mlp = torch.nn.Conv2d(c_in, c_out, kernel_size=(1, 1), padding=(0,0), stride=(1,1), bias=True)\n\n    def forward(self,x):\n        return self.mlp(x)\n\nclass gcn(nn.Module):\n    def __init__(self,c_in,c_out,dropout,support_len=3,order=2):\n        super(gcn,self).__init__()\n        self.nconv = nconv()\n        c_in = (order*support_len+1)*c_in\n        self.mlp = linear(c_in,c_out)\n        self.dropout = dropout\n        self.order = order\n\n    def forward(self,x,support):\n        out = [x]\n        for a in support:\n            x1 = self.nconv(x,a)\n            out.append(x1)\n            for k in range(2, self.order + 1):\n                x2 = self.nconv(x1,a)\n                out.append(x2)\n                x1 = x2\n\n        h = torch.cat(out,dim=1)\n        h = self.mlp(h)\n        h = F.dropout(h, self.dropout, training=self.training)\n        return h\n\n\nclass gwnet(nn.Module):\n    \"\"\"\n\n    References:\n        - `Graph wavenet for deep spatial-temporal graph modeling.\n          <https://www.ijcai.org/proceedings/2019/0264.pdf>`_.\n        - `A PyTorch implementation of the GraphWaveNet model  (nnzhan)\n          <https://github.com/nnzhan/Graph-WaveNet>`_.\n\n    Args:\n        device(torch.device): Which device use to train.\n        num_node(int): Number of blocks.\n        drop_out(int): Number of input channels.\n        supports(int): Order of chebyshev polynomial.\n        gcn_bool(int): Number of chebyshev filter.\n        addaptadj(bool): Whether to add adaptive adjacent matrix.\n        aptinit(torch.tensor): Initialization of adjacent matrix.\n        in_dim(int): Number of input's dimension.\n        out_dim(int): Number of output's dimension.\n        residual_channels(int): Number of channels after residual module.\n        dilation_channels(int): Number of channels after dilation module.\n        skip_channels(int): Number of skip channels.\n        end_channels(int): Number of end channels.\n        kernel_size(int): Kernel Size for dilation convolution.\n        blocks(int): Number of block.\n        layers(int): Number of layer.\n    \"\"\"\n    def __init__(self, device, num_node, dropout=0.3, supports=None, gcn_bool=True, addaptadj=True, aptinit=None, in_dim=2,out_dim=12,residual_channels=32,dilation_channels=32,skip_channels=256,end_channels=512,kernel_size=2,blocks=4,layers=2):\n        super(gwnet, self).__init__()\n        self.dropout = dropout\n        self.blocks = blocks\n        self.layers = layers\n        self.gcn_bool = gcn_bool\n        self.addaptadj = addaptadj\n\n        self.filter_convs = nn.ModuleList()\n        self.gate_convs = nn.ModuleList()\n        self.residual_convs = nn.ModuleList()\n        self.skip_convs = nn.ModuleList()\n        self.bn = nn.ModuleList()\n        self.gconv = nn.ModuleList()\n\n        self.start_conv = nn.Conv2d(in_channels=in_dim,\n                                    out_channels=residual_channels,\n                                    kernel_size=(1,1))\n        self.supports = supports\n\n        receptive_field = 1\n\n        self.supports_len = 0\n        if supports is not None:\n            self.supports_len += len(supports)\n\n        if gcn_bool and addaptadj:\n            if aptinit is None:\n                if supports is None:\n                    self.supports = []\n                self.nodevec1 = nn.Parameter(torch.randn(num_node, 10).to(device), requires_grad=True).to(device)\n                self.nodevec2 = nn.Parameter(torch.randn(10, num_node).to(device), requires_grad=True).to(device)\n                self.supports_len +=1\n            else:\n                if supports is None:\n                    self.supports = []\n                m, p, n = torch.svd(aptinit)\n                initemb1 = torch.mm(m[:, :10], torch.diag(p[:10] ** 0.5))\n                initemb2 = torch.mm(torch.diag(p[:10] ** 0.5), n[:, :10].t())\n                self.nodevec1 = nn.Parameter(initemb1, requires_grad=True).to(device)\n                self.nodevec2 = nn.Parameter(initemb2, requires_grad=True).to(device)\n                self.supports_len += 1\n\n\n\n\n        for b in range(blocks):\n            additional_scope = kernel_size - 1\n            new_dilation = 1\n            for i in range(layers):\n                # dilated convolutions\n                self.filter_convs.append(nn.Conv2d(in_channels=residual_channels,\n                                                   out_channels=dilation_channels,\n                                                   kernel_size=(1,kernel_size),dilation=new_dilation))\n\n                self.gate_convs.append(nn.Conv1d(in_channels=residual_channels,\n                                                 out_channels=dilation_channels,\n                                                 kernel_size=(1, kernel_size), dilation=new_dilation))\n\n                # 1x1 convolution for residual connection\n                self.residual_convs.append(nn.Conv1d(in_channels=dilation_channels,\n                                                     out_channels=residual_channels,\n                                                     kernel_size=(1, 1)))\n\n                # 1x1 convolution for skip connection\n                self.skip_convs.append(nn.Conv1d(in_channels=dilation_channels,\n                                                 out_channels=skip_channels,\n                                                 kernel_size=(1, 1)))\n                self.bn.append(nn.BatchNorm2d(residual_channels))\n                new_dilation *=2\n                receptive_field += additional_scope\n                additional_scope *= 2\n                if self.gcn_bool:\n                    self.gconv.append(gcn(dilation_channels,residual_channels,dropout,support_len=self.supports_len))\n\n\n\n        self.end_conv_1 = nn.Conv2d(in_channels=skip_channels,\n                                  out_channels=end_channels,\n                                  kernel_size=(1,1),\n                                  bias=True)\n\n        self.end_conv_2 = nn.Conv2d(in_channels=end_channels,\n                                    out_channels=out_dim,\n                                    kernel_size=(1,1),\n                                    bias=True)\n\n        self.receptive_field = receptive_field\n\n\n\n    def forward(self, input):\n        in_len = input.size(3)\n        if in_len<self.receptive_field:\n            x = nn.functional.pad(input,(self.receptive_field-in_len,0,0,0))\n        else:\n            x = input\n        x = self.start_conv(x)\n        skip = 0\n\n        # calculate the current adaptive adj matrix once per iteration\n        new_supports = None\n        if self.gcn_bool and self.addaptadj and self.supports is not None:\n            adp = F.softmax(F.relu(torch.mm(self.nodevec1, self.nodevec2)), dim=1)\n            new_supports = self.supports + [adp]\n\n        # WaveNet layers\n        for i in range(self.blocks * self.layers):\n\n            #            |----------------------------------------|     *residual*\n            #            |                                        |\n            #            |    |-- conv -- tanh --|                |\n            # -> dilate -|----|                  * ----|-- 1x1 -- + -->\t*input*\n            #                 |-- conv -- sigm --|     |\n            #                                         1x1\n            #                                          |\n            # ---------------------------------------> + ------------->\t*skip*\n\n            #(dilation, init_dilation) = self.dilations[i]\n\n            #residual = dilation_func(x, dilation, init_dilation, i)\n            residual = x\n            # dilated convolution\n            filter = self.filter_convs[i](residual)\n            filter = torch.tanh(filter)\n            gate = self.gate_convs[i](residual)\n            gate = torch.sigmoid(gate)\n            x = filter * gate\n\n            # parametrized skip connection\n\n            s = x\n            s = self.skip_convs[i](s)\n            try:\n                skip = skip[:, :, :,  -s.size(3):]\n            except:\n                skip = 0\n            skip = s + skip\n\n\n            if self.gcn_bool and self.supports is not None:\n                if self.addaptadj:\n                    x = self.gconv[i](x, new_supports)\n                else:\n                    x = self.gconv[i](x,self.supports)\n            else:\n                x = self.residual_convs[i](x)\n\n            x = x + residual[:, :, :, -x.size(3):]\n\n\n            x = self.bn[i](x)\n\n        x = F.relu(skip)\n        x = F.relu(self.end_conv_1(x))\n        x = self.end_conv_2(x)\n        return x"
  },
  {
    "path": "UCTB/model/HM.py",
    "content": "import numpy as np\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n\nclass HM(object):\n    '''\n    Historical Mean. A naive method that simply return average of hisrory data of each time slot.\n\n    Args:\n        c(int): The number of time slots of closeness history. \n        p (int): The number of time slots of period history which presents daily feature.\n        t (int): The number of time slots of trend history which presents weekly feature.\n        Note that `(c, p, t)` cannot all be zero at the same time. They denote how many\n        features should be considerd in average.\n    '''\n    def __init__(self, c, p, t):\n\n        self.c = c\n        self.p = p\n        self.t = t\n\n        if self.c == 0 and self.p == 0 and self.t == 0:\n            raise ValueError('c p t cannot all be zero at the same time')\n\n    def predict(self, closeness_feature, period_feature, trend_feature):\n        '''\n        Give closeness, period and trend history values and then use their averages as predict.\n        '''\n        prediction = []\n\n        if self.c > 0:\n            prediction.append(closeness_feature[:, :, :, 0])\n\n        if self.p > 0:\n            prediction.append(period_feature[:, :, :, 0])\n\n        if self.t > 0:\n            prediction.append(trend_feature[:, :, :, 0])\n\n        prediction = np.mean(np.concatenate(prediction, axis=-1), axis=-1, keepdims=True)\n\n        return prediction\n"
  },
  {
    "path": "UCTB/model/HMM.py",
    "content": "import numpy as np\r\nfrom hmmlearn import hmm\r\n\r\n\r\nclass HMM(object):\r\n    def __init__(self, num_components, n_iter, hmm_kernal=hmm.GaussianHMM):\r\n\r\n        self._num_components = num_components\r\n        self._iter = n_iter\r\n\r\n        self._hmm = hmm_kernal(n_components=self._num_components, n_iter=self._iter, covariance_type='full')\r\n\r\n    def fit(self, x):\r\n        self._hmm.fit(x)\r\n        if self._hmm.monitor_.converged:\r\n            print('Status: converged')\r\n\r\n    def predict(self, x, length):\r\n        # predict the state for each element of X\r\n        # and store the last state\r\n        last_state = self._hmm.predict_proba(x)[-1:]\r\n\r\n        pre_state = []\r\n        pre_observation = []\r\n\r\n        for i in range(length):\r\n            # predict the state of next moment using the transmat\r\n            last_state = np.dot(last_state, self._hmm.transmat_)\r\n\r\n            pre_state.append(last_state)\r\n\r\n            # dot product between the state-probability and state-means\r\n            pre_observation.append([np.dot(last_state, self._hmm.means_)[0][0]])\r\n\r\n        return pre_observation"
  },
  {
    "path": "UCTB/model/MCSTGCN.py",
    "content": "import keras\nimport tensorflow as tf\n\nfrom ..model_unit import BaseModel\nfrom ..model_unit import GAL, GCL\nfrom ..model_unit import DCGRUCell\nfrom ..model_unit import GCLSTMCell\n\n\nclass MCSTGCN(BaseModel):\n    \"\"\"\n        Args:\n            num_node(int): Number of nodes in the graph, e.g. number of stations in NYC-Bike dataset.\n            external_dim(int): Dimension of the external feature, e.g. temperature and wind are two dimension.\n            closeness_len(int): The length of closeness data history. The former consecutive ``closeness_len`` time slots\n            of data will be used as closeness history.\n            period_len(int): The length of period data history. The data of exact same time slots in former consecutive\n            ``period_len`` days will be used as period history.\n            trend_len(int): The length of trend data history. The data of exact same time slots in former consecutive\n            ``trend_len`` weeks (every seven days) will be used as trend history.\n            num_graph(int): Number of graphs used in MCSTGCN.\n            gcn_k(int): The highest order of Chebyshev Polynomial approximation in GCN.\n            gcn_layers(int): Number of GCN layers.\n            gclstm_layers(int): Number of STRNN layers, it works on all modes of MCSTGCN such as GCLSTM and DCRNN.\n            num_hidden_units(int): Number of hidden units of RNN.\n            num_dense_units(int): Number of dense units.\n            graph_merge_gal_units(int): Number of units in GAL for merging different graph features.\n                Only works when graph_merge='gal'\n            graph_merge_gal_num_heads(int): Number of heads in GAL for merging different graph features.\n                Only works when graph_merge='gal'\n            temporal_merge_gal_units(int): Number of units in GAL for merging different temporal features.\n                Only works when temporal_merge='gal'\n            temporal_merge_gal_num_heads(int): Number of heads in GAL for merging different temporal features.\n                Only works when temporal_merge='gal'\n            st_method(str): must in ['GCLSTM', 'DCRNN', 'GRU', 'LSTM'], which refers to different\n                spatial-temporal modeling methods.\n                'GCLSTM': GCN for modeling spatial feature, LSTM for modeling temporal feature.\n                'DCRNN': Diffusion Convolution for modeling spatial feature, GRU for modeling temporam frature.\n                'GRU': Ignore the spatial, and model the temporal feature using GRU\n                'LSTM': Ignore the spatial, and model the temporal feature using LSTM\n            temporal_merge(str): must in ['gal', 'concat'], refers to different temporal merging methods,\n                'gal': merge using GAL,\n                'concat': merge by concat and dense\n            graph_merge(str): must in ['gal', 'concat'], refers to different graph merging methods,\n                'gal': merge using GAL,\n                'concat': merge by concat and dense\n            output_activation(function): activation function, e.g. tf.nn.tanh\n            lr(float): Learning rate. Default: 1e-5\n            code_version(str): Current version of this model code, which will be used as filename for saving the model\n            model_dir(str): The directory to store model files. Default:'model_dir'.\n            gpu_device(str): To specify the GPU to use. Default: '0'.\n        \"\"\"\n\n    def __init__(self,\n                 num_node,\n                 external_dim,\n                 closeness_len,\n                 period_len,\n                 trend_len,\n\n                 # gcn parameters\n                 num_graph=1,\n                 gcn_k=1,\n                 gcn_layers=1,\n                 gclstm_layers=1,\n\n                 # dense units\n                 num_hidden_units=64,\n                 # LSTM units\n                 num_dense_units=32,\n\n                 # merge parameters\n                 graph_merge_gal_units=32,\n                 graph_merge_gal_num_heads=2,\n                 temporal_merge_gal_units=64,\n                 temporal_merge_gal_num_heads=2,\n\n                 # network structure parameters\n                 st_method='GCLSTM',  # gclstm\n                 temporal_merge='gal',  # gal\n                 graph_merge='gal',  # concat\n\n                 output_activation=tf.nn.sigmoid,\n\n                 lr=1e-4,\n                 code_version='MCSTGCN-QuickStart',\n                 model_dir='model_dir',\n                 gpu_device='0', **kwargs):\n\n        super(MCSTGCN, self).__init__(code_version=code_version, model_dir=model_dir, gpu_device=gpu_device)\n\n        self._num_node = num_node\n        self._gcn_k = gcn_k\n        self._gcn_layer = gcn_layers\n        self._graph_merge_gal_units = graph_merge_gal_units\n        self._graph_merge_gal_num_heads = graph_merge_gal_num_heads\n        self._temporal_merge_gal_units = temporal_merge_gal_units\n        self._temporal_merge_gal_num_heads = temporal_merge_gal_num_heads\n        self._gclstm_layers = gclstm_layers\n        self._num_graph = num_graph\n        self._external_dim = external_dim\n        self._output_activation = output_activation\n\n        self._st_method = st_method.upper()\n        self._temporal_merge = temporal_merge\n        self._graph_merge = graph_merge\n\n        self._closeness_len = int(closeness_len)\n        self._period_len = int(period_len)\n        self._trend_len = int(trend_len)\n        self._num_hidden_unit = num_hidden_units\n        self._num_dense_units = num_dense_units\n        self._lr = lr\n    \n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n\n            temporal_features = []\n\n            if self._closeness_len is not None and self._closeness_len > 0:\n                closeness_feature = tf.placeholder(tf.float32, [None, None, self._closeness_len, 1],\n                                                   name='closeness_feature')\n                self._input['closeness_feature'] = closeness_feature.name\n                temporal_features.append([self._closeness_len, closeness_feature, 'closeness_feature'])\n\n            if self._period_len is not None and self._period_len > 0:\n                period_feature = tf.placeholder(tf.float32, [None, None, self._period_len, 1],\n                                                name='period_feature')\n                self._input['period_feature'] = period_feature.name\n                temporal_features.append([self._period_len, period_feature, 'period_feature'])\n\n            if self._trend_len is not None and self._trend_len > 0:\n                trend_feature = tf.placeholder(tf.float32, [None, None, self._trend_len, 1],\n                                               name='trend_feature')\n                self._input['trend_feature'] = trend_feature.name\n                temporal_features.append([self._trend_len, trend_feature, 'trend_feature'])\n\n            if len(temporal_features) > 0:\n                target = tf.placeholder(tf.float32, [None, None, 1], name='target')\n                laplace_matrix = tf.placeholder(tf.float32, [self._num_graph, None, None], name='laplace_matrix')\n                self._input['target'] = target.name\n                self._input['laplace_matrix'] = laplace_matrix.name\n            else:\n                raise ValueError('closeness_len, period_len, trend_len cannot all be zero')\n\n            graph_outputs_list = []\n\n\n            for i, time_step, target_tensor, given_name in enumerate(temporal_features):\n                temporal_features[i][1] = GCL.add_multi_gc_layers(tf.reshape(traffic_flow, [-1, self._num_node, self._input_dim]),\n                                                                  gcn_k=1, gcn_l=1, output_size=self._input_dim,\n                                                                  laplacian_matrix=laplacian_matrix[0],\n                                                                  activation=tf.nn.tanh)\n                pass\n    \n\n\n            for graph_index in range(self._num_graph):\n\n\n                gcn_output = GCL.add_multi_gc_layers(tf.reshape(traffic_flow, [-1, self._num_node, self._input_dim]),\n                                                    gcn_k=1, gcn_l=1, output_size=self._input_dim,\n                                                    laplacian_matrix=laplacian_matrix[graph_index],\n                                                    activation=tf.nn.tanh)\n\n                f_k_g = tf.reshape(f_k_g, [-1, self._T, self._num_node, self._input_dim])\n\n\n\n                outputs_temporal = []\n\n\n                for time_step, target_tensor, given_name in temporal_features:\n\n\n\n\n\n                    if self._st_method == 'GCLSTM':\n\n                        multi_layer_cell = tf.keras.layers.StackedRNNCells(\n                            [GCLSTMCell(units=self._num_hidden_unit, num_node=self._num_node,\n                                        laplacian_matrix=laplace_matrix[graph_index],\n                                        gcn_k=self._gcn_k, gcn_l=self._gcn_layer)\n                                for _ in range(self._gclstm_layers)])\n\n                        outputs = tf.keras.layers.RNN(multi_layer_cell)(tf.reshape(target_tensor, [-1, time_step, 1]))\n\n                        st_outputs = tf.reshape(outputs, [-1, 1, self._num_hidden_unit])\n\n                    elif self._st_method == 'DCRNN':\n\n                        cell = DCGRUCell(self._num_hidden_unit, 1, self._num_graph,\n                                            # laplace_matrix will be diffusion_matrix when self._st_method == 'DCRNN'\n                                            laplace_matrix,\n                                            max_diffusion_step=self._gcn_k,\n                                            num_node=self._num_node, name=str(graph_index) + given_name)\n\n                        encoding_cells = [cell] * self._gclstm_layers\n                        encoding_cells = tf.contrib.rnn.MultiRNNCell(encoding_cells, state_is_tuple=True)\n\n                        inputs_unstack = tf.unstack(tf.reshape(target_tensor, [-1, self._num_node, time_step]),\n                                                    axis=-1)\n\n                        outputs, _ = \\\n                            tf.contrib.rnn.static_rnn(encoding_cells, inputs_unstack, dtype=tf.float32)\n\n                        st_outputs = tf.reshape(outputs[-1], [-1, 1, self._num_hidden_unit])\n\n                    elif self._st_method == 'GRU':\n\n                        cell = tf.keras.layers.GRUCell(units=self._num_hidden_unit)\n                        multi_layer_gru = tf.keras.layers.StackedRNNCells([cell] * self._gclstm_layers)\n                        outputs = tf.keras.layers.RNN(multi_layer_gru)(\n                            tf.reshape(target_tensor, [-1, time_step, 1]))\n                        st_outputs = tf.reshape(outputs, [-1, 1, self._num_hidden_unit])\n\n                    elif self._st_method == 'LSTM':\n\n                        cell = tf.keras.layers.LSTMCell(units=self._num_hidden_unit)\n                        multi_layer_gru = tf.keras.layers.StackedRNNCells([cell] * self._gclstm_layers)\n                        outputs = tf.keras.layers.RNN(multi_layer_gru)(\n                            tf.reshape(target_tensor, [-1, time_step, 1]))\n                        st_outputs = tf.reshape(outputs, [-1, 1, self._num_hidden_unit])\n\n                    outputs_temporal.append(st_outputs)\n\n                if self._temporal_merge == 'concat':\n                    \n                    graph_outputs_list.append(tf.concat(outputs_temporal, axis=-1))\n\n                elif self._temporal_merge == 'gal':\n\n                    _, gal_output = GAL.add_ga_layer_matrix(inputs=tf.concat(outputs_temporal, axis=-2),\n                                                            units=self._temporal_merge_gal_units,\n                                                            num_head=self._temporal_merge_gal_num_heads)\n\n                    graph_outputs_list.append(tf.reduce_mean(gal_output, axis=-2, keepdims=True))\n\n\n\n\n\n\n                if self._st_method in ['GCLSTM', 'DCRNN', 'GRU', 'LSTM']:\n\n                    outputs_temporal = []\n\n                    for time_step, target_tensor, given_name in temporal_features:\n\n                        if self._st_method == 'GCLSTM':\n\n                            multi_layer_cell = tf.keras.layers.StackedRNNCells(\n                                [GCLSTMCell(units=self._num_hidden_unit, num_node=self._num_node,\n                                            laplacian_matrix=laplace_matrix[graph_index],\n                                            gcn_k=self._gcn_k, gcn_l=self._gcn_layer)\n                                 for _ in range(self._gclstm_layers)])\n\n                            outputs = tf.keras.layers.RNN(multi_layer_cell)(tf.reshape(target_tensor, [-1, time_step, 1]))\n\n                            st_outputs = tf.reshape(outputs, [-1, 1, self._num_hidden_unit])\n\n                        elif self._st_method == 'DCRNN':\n\n                            cell = DCGRUCell(self._num_hidden_unit, 1, self._num_graph,\n                                             # laplace_matrix will be diffusion_matrix when self._st_method == 'DCRNN'\n                                             laplace_matrix,\n                                             max_diffusion_step=self._gcn_k,\n                                             num_node=self._num_node, name=str(graph_index) + given_name)\n\n                            encoding_cells = [cell] * self._gclstm_layers\n                            encoding_cells = tf.contrib.rnn.MultiRNNCell(encoding_cells, state_is_tuple=True)\n\n                            inputs_unstack = tf.unstack(tf.reshape(target_tensor, [-1, self._num_node, time_step]),\n                                                        axis=-1)\n\n                            outputs, _ = \\\n                                tf.contrib.rnn.static_rnn(encoding_cells, inputs_unstack, dtype=tf.float32)\n\n                            st_outputs = tf.reshape(outputs[-1], [-1, 1, self._num_hidden_unit])\n\n                        elif self._st_method == 'GRU':\n\n                            cell = tf.keras.layers.GRUCell(units=self._num_hidden_unit)\n                            multi_layer_gru = tf.keras.layers.StackedRNNCells([cell] * self._gclstm_layers)\n                            outputs = tf.keras.layers.RNN(multi_layer_gru)(\n                                tf.reshape(target_tensor, [-1, time_step, 1]))\n                            st_outputs = tf.reshape(outputs, [-1, 1, self._num_hidden_unit])\n\n                        elif self._st_method == 'LSTM':\n\n                            cell = tf.keras.layers.LSTMCell(units=self._num_hidden_unit)\n                            multi_layer_gru = tf.keras.layers.StackedRNNCells([cell] * self._gclstm_layers)\n                            outputs = tf.keras.layers.RNN(multi_layer_gru)(\n                                tf.reshape(target_tensor, [-1, time_step, 1]))\n                            st_outputs = tf.reshape(outputs, [-1, 1, self._num_hidden_unit])\n\n                        outputs_temporal.append(st_outputs)\n\n                    if self._temporal_merge == 'concat':\n                        \n                        graph_outputs_list.append(tf.concat(outputs_temporal, axis=-1))\n\n                    elif self._temporal_merge == 'gal':\n\n                        _, gal_output = GAL.add_ga_layer_matrix(inputs=tf.concat(outputs_temporal, axis=-2),\n                                                                units=self._temporal_merge_gal_units,\n                                                                num_head=self._temporal_merge_gal_num_heads)\n\n                        graph_outputs_list.append(tf.reduce_mean(gal_output, axis=-2, keepdims=True))\n\n            if self._num_graph > 1:\n\n                if self._graph_merge == 'gal':\n                    # (graph, inputs_name, units, num_head, activation=tf.nn.leaky_relu)\n                    _, gal_output = GAL.add_ga_layer_matrix(inputs=tf.concat(graph_outputs_list, axis=-2),\n                                                            units=self._graph_merge_gal_units,\n                                                            num_head=self._graph_merge_gal_num_heads)\n                    dense_inputs = tf.reduce_mean(gal_output, axis=-2, keepdims=True)\n\n                elif self._graph_merge == 'concat':\n\n                    dense_inputs = tf.concat(graph_outputs_list, axis=-1)\n\n            else:\n\n                dense_inputs = graph_outputs_list[-1]\n\n            dense_inputs = tf.reshape(dense_inputs, [-1, self._num_node, 1, dense_inputs.get_shape()[-1].value])\n\n            dense_inputs = tf.keras.layers.BatchNormalization(axis=-1, name='feature_map')(dense_inputs)\n\n            # external dims\n            if self._external_dim is not None and self._external_dim > 0:\n                external_input = tf.placeholder(tf.float32, [None, self._external_dim])\n                self._input['external_feature'] = external_input.name\n                external_dense = tf.keras.layers.Dense(units=10)(external_input)\n                external_dense = tf.tile(tf.reshape(external_dense, [-1, 1, 1, 10]),\n                                         [1, tf.shape(dense_inputs)[1], tf.shape(dense_inputs)[2], 1])\n                dense_inputs = tf.concat([dense_inputs, external_dense], axis=-1)\n\n            dense_output0 = tf.keras.layers.Dense(units=self._num_dense_units,\n                                                  activation=tf.nn.tanh,\n                                                  use_bias=True,\n                                                  kernel_initializer='glorot_uniform',\n                                                  bias_initializer='zeros',\n                                                  kernel_regularizer=tf.keras.regularizers.l2(0.01),\n                                                  bias_regularizer=tf.keras.regularizers.l2(0.01)\n                                                  )(dense_inputs)\n\n            dense_output1 = tf.keras.layers.Dense(units=self._num_dense_units,\n                                                  activation=tf.nn.tanh,\n                                                  use_bias=True,\n                                                  kernel_initializer='glorot_uniform',\n                                                  bias_initializer='zeros',\n                                                  kernel_regularizer=tf.keras.regularizers.l2(0.01),\n                                                  bias_regularizer=tf.keras.regularizers.l2(0.01)\n                                                  )(dense_output0)\n\n            pre_output = tf.keras.layers.Dense(units=1,\n                                               activation=tf.nn.tanh,\n                                               use_bias=True,\n                                               kernel_initializer='glorot_uniform',\n                                               bias_initializer='zeros',\n                                               kernel_regularizer=tf.keras.regularizers.l2(0.01),\n                                               bias_regularizer=tf.keras.regularizers.l2(0.01)\n                                               )(dense_output1)\n\n            prediction = tf.reshape(pre_output, [-1, self._num_node, 1], name='prediction')\n\n            loss_pre = tf.sqrt(tf.reduce_mean(tf.square(target - prediction)), name='loss')\n\n            train_op = tf.train.AdamOptimizer(self._lr).minimize(loss_pre, name='train_op')\n\n            # record output\n            self._output['prediction'] = prediction.name\n            self._output['loss'] = loss_pre.name\n\n            # record train operation\n            self._op['train_op'] = train_op.name\n\n        super(MCSTGCN, self).build(init_vars, max_to_keep)\n\n    # Define your '_get_feed_dict function‘, map your input to the tf-model\n    def _get_feed_dict(self,\n                       laplace_matrix,\n                       closeness_feature=None,\n                       period_feature=None,\n                       trend_feature=None,\n                       target=None,\n                       external_feature=None):\n        feed_dict = {\n            'laplace_matrix': laplace_matrix,\n        }\n        if target is not None:\n            feed_dict['target'] = target\n        if self._external_dim is not None and self._external_dim > 0:\n            feed_dict['external_feature'] = external_feature\n        if self._closeness_len is not None and self._closeness_len > 0:\n            feed_dict['closeness_feature'] = closeness_feature\n        if self._period_len is not None and self._period_len > 0:\n            feed_dict['period_feature'] = period_feature\n        if self._trend_len is not None and self._trend_len > 0:\n            feed_dict['trend_feature'] = trend_feature\n        return feed_dict\n"
  },
  {
    "path": "UCTB/model/MTGNN.py",
    "content": "from __future__ import division\nimport torch\nimport torch.nn as nn\nfrom torch.nn import init\nimport numbers\nimport torch.nn.functional as F\nimport pdb\n\nclass nconv(nn.Module):\n    def __init__(self):\n        super(nconv,self).__init__()\n\n    def forward(self,x, A):\n        x = torch.einsum('ncwl,vw->ncvl',(x,A))\n        return x.contiguous()\n\nclass dy_nconv(nn.Module):\n    def __init__(self):\n        super(dy_nconv,self).__init__()\n\n    def forward(self,x, A):\n        x = torch.einsum('ncvl,nvwl->ncwl',(x,A))\n        return x.contiguous()\n\nclass linear(nn.Module):\n    def __init__(self,c_in,c_out,bias=True):\n        super(linear,self).__init__()\n        self.mlp = torch.nn.Conv2d(c_in, c_out, kernel_size=(1, 1), padding=(0,0), stride=(1,1), bias=bias)\n\n    def forward(self,x):\n        return self.mlp(x)\n\n\nclass prop(nn.Module):\n    def __init__(self,c_in,c_out,gdep,dropout,alpha):\n        super(prop, self).__init__()\n        self.nconv = nconv()\n        self.mlp = linear(c_in,c_out)\n        self.gdep = gdep\n        self.dropout = dropout\n        self.alpha = alpha\n\n    def forward(self,x,adj):\n        adj = adj + torch.eye(adj.size(0)).to(x.device)\n        d = adj.sum(1)\n        h = x\n        dv = d\n        a = adj / dv.view(-1, 1)\n        for i in range(self.gdep):\n            h = self.alpha*x + (1-self.alpha)*self.nconv(h,a)\n        ho = self.mlp(h)\n        return ho\n\n\nclass mixprop(nn.Module):\n    def __init__(self,c_in,c_out,gdep,dropout,alpha):\n        super(mixprop, self).__init__()\n        self.nconv = nconv()\n        self.mlp = linear((gdep+1)*c_in,c_out)\n        self.gdep = gdep\n        self.dropout = dropout\n        self.alpha = alpha\n\n\n    def forward(self,x,adj):\n        adj = adj + torch.eye(adj.size(0)).to(x.device)\n        d = adj.sum(1)\n        h = x\n        out = [h]\n        a = adj / d.view(-1, 1)\n        for i in range(self.gdep):\n            h = self.alpha*x + (1-self.alpha)*self.nconv(h,a)\n            out.append(h)\n        ho = torch.cat(out,dim=1)\n        ho = self.mlp(ho)\n        return ho\n\nclass dy_mixprop(nn.Module):\n    def __init__(self,c_in,c_out,gdep,dropout,alpha):\n        super(dy_mixprop, self).__init__()\n        self.nconv = dy_nconv()\n        self.mlp1 = linear((gdep+1)*c_in,c_out)\n        self.mlp2 = linear((gdep+1)*c_in,c_out)\n\n        self.gdep = gdep\n        self.dropout = dropout\n        self.alpha = alpha\n        self.lin1 = linear(c_in,c_in)\n        self.lin2 = linear(c_in,c_in)\n\n\n    def forward(self,x):\n        #adj = adj + torch.eye(adj.size(0)).to(x.device)\n        #d = adj.sum(1)\n        x1 = torch.tanh(self.lin1(x))\n        x2 = torch.tanh(self.lin2(x))\n        adj = self.nconv(x1.transpose(2,1),x2)\n        adj0 = torch.softmax(adj, dim=2)\n        adj1 = torch.softmax(adj.transpose(2,1), dim=2)\n\n        h = x\n        out = [h]\n        for i in range(self.gdep):\n            h = self.alpha*x + (1-self.alpha)*self.nconv(h,adj0)\n            out.append(h)\n        ho = torch.cat(out,dim=1)\n        ho1 = self.mlp1(ho)\n\n\n        h = x\n        out = [h]\n        for i in range(self.gdep):\n            h = self.alpha * x + (1 - self.alpha) * self.nconv(h, adj1)\n            out.append(h)\n        ho = torch.cat(out, dim=1)\n        ho2 = self.mlp2(ho)\n\n        return ho1+ho2\n\n\n\nclass dilated_1D(nn.Module):\n    def __init__(self, cin, cout, dilation_factor=2):\n        super(dilated_1D, self).__init__()\n        self.tconv = nn.ModuleList()\n        self.kernel_set = [2,3,6,7]\n        self.tconv = nn.Conv2d(cin,cout,(1,7),dilation=(1,dilation_factor))\n\n    def forward(self,input):\n        x = self.tconv(input)\n        return x\n\nclass dilated_inception(nn.Module):\n    def __init__(self, cin, cout, dilation_factor=2):\n        super(dilated_inception, self).__init__()\n        self.tconv = nn.ModuleList()\n        self.kernel_set = [2,3,6,7]\n        cout = int(cout/len(self.kernel_set))\n        for kern in self.kernel_set:\n            self.tconv.append(nn.Conv2d(cin,cout,(1,kern),dilation=(1,dilation_factor)))\n\n    def forward(self,input):\n        x = []\n        for i in range(len(self.kernel_set)):\n            x.append(self.tconv[i](input))\n        for i in range(len(self.kernel_set)):\n            x[i] = x[i][...,-x[-1].size(3):]\n        x = torch.cat(x,dim=1)\n        return x\n\n\nclass graph_constructor(nn.Module):\n    def __init__(self, nnodes, k, dim, device, alpha=3, static_feat=None):\n        super(graph_constructor, self).__init__()\n        self.nnodes = nnodes\n        if static_feat is not None:\n            xd = static_feat.shape[1]\n            self.lin1 = nn.Linear(xd, dim)\n            self.lin2 = nn.Linear(xd, dim)\n        else:\n            self.emb1 = nn.Embedding(nnodes, dim)\n            self.emb2 = nn.Embedding(nnodes, dim)\n            self.lin1 = nn.Linear(dim,dim)\n            self.lin2 = nn.Linear(dim,dim)\n\n        self.device = device\n        self.k = k\n        self.dim = dim\n        self.alpha = alpha\n        self.static_feat = static_feat\n\n    def forward(self, idx):\n        if self.static_feat is None:\n            nodevec1 = self.emb1(idx)\n            nodevec2 = self.emb2(idx)\n        else:\n            nodevec1 = self.static_feat[idx,:]\n            nodevec2 = nodevec1\n\n        nodevec1 = torch.tanh(self.alpha*self.lin1(nodevec1))\n        nodevec2 = torch.tanh(self.alpha*self.lin2(nodevec2))\n\n        a = torch.mm(nodevec1, nodevec2.transpose(1,0))-torch.mm(nodevec2, nodevec1.transpose(1,0))\n        adj = F.relu(torch.tanh(self.alpha*a))\n        mask = torch.zeros(idx.size(0), idx.size(0)).to(self.device)\n        mask.fill_(float('0'))\n        s1,t1 = (adj + torch.rand_like(adj)*0.01).topk(self.k,1)\n        mask.scatter_(1,t1,s1.fill_(1))\n        adj = adj*mask\n        return adj\n\n    def fullA(self, idx):\n        if self.static_feat is None:\n            nodevec1 = self.emb1(idx)\n            nodevec2 = self.emb2(idx)\n        else:\n            nodevec1 = self.static_feat[idx,:]\n            nodevec2 = nodevec1\n\n        nodevec1 = torch.tanh(self.alpha*self.lin1(nodevec1))\n        nodevec2 = torch.tanh(self.alpha*self.lin2(nodevec2))\n\n        a = torch.mm(nodevec1, nodevec2.transpose(1,0))-torch.mm(nodevec2, nodevec1.transpose(1,0))\n        adj = F.relu(torch.tanh(self.alpha*a))\n        return adj\n\nclass graph_global(nn.Module):\n    def __init__(self, nnodes, k, dim, device, alpha=3, static_feat=None):\n        super(graph_global, self).__init__()\n        self.nnodes = nnodes\n        self.A = nn.Parameter(torch.randn(nnodes, nnodes).to(device), requires_grad=True).to(device)\n\n    def forward(self, idx):\n        return F.relu(self.A)\n\n\nclass graph_undirected(nn.Module):\n    def __init__(self, nnodes, k, dim, device, alpha=3, static_feat=None):\n        super(graph_undirected, self).__init__()\n        self.nnodes = nnodes\n        if static_feat is not None:\n            xd = static_feat.shape[1]\n            self.lin1 = nn.Linear(xd, dim)\n        else:\n            self.emb1 = nn.Embedding(nnodes, dim)\n            self.lin1 = nn.Linear(dim,dim)\n\n        self.device = device\n        self.k = k\n        self.dim = dim\n        self.alpha = alpha\n        self.static_feat = static_feat\n\n    def forward(self, idx):\n        if self.static_feat is None:\n            nodevec1 = self.emb1(idx)\n            nodevec2 = self.emb1(idx)\n        else:\n            nodevec1 = self.static_feat[idx,:]\n            nodevec2 = nodevec1\n\n        nodevec1 = torch.tanh(self.alpha*self.lin1(nodevec1))\n        nodevec2 = torch.tanh(self.alpha*self.lin1(nodevec2))\n\n        a = torch.mm(nodevec1, nodevec2.transpose(1,0))\n        adj = F.relu(torch.tanh(self.alpha*a))\n        mask = torch.zeros(idx.size(0), idx.size(0)).to(self.device)\n        mask.fill_(float('0'))\n        s1,t1 = adj.topk(self.k,1)\n        mask.scatter_(1,t1,s1.fill_(1))\n        adj = adj*mask\n        return adj\n\n\n\nclass graph_directed(nn.Module):\n    def __init__(self, nnodes, k, dim, device, alpha=3, static_feat=None):\n        super(graph_directed, self).__init__()\n        self.nnodes = nnodes\n        if static_feat is not None:\n            xd = static_feat.shape[1]\n            self.lin1 = nn.Linear(xd, dim)\n            self.lin2 = nn.Linear(xd, dim)\n        else:\n            self.emb1 = nn.Embedding(nnodes, dim)\n            self.emb2 = nn.Embedding(nnodes, dim)\n            self.lin1 = nn.Linear(dim,dim)\n            self.lin2 = nn.Linear(dim,dim)\n\n        self.device = device\n        self.k = k\n        self.dim = dim\n        self.alpha = alpha\n        self.static_feat = static_feat\n\n    def forward(self, idx):\n        if self.static_feat is None:\n            nodevec1 = self.emb1(idx)\n            nodevec2 = self.emb2(idx)\n        else:\n            nodevec1 = self.static_feat[idx,:]\n            nodevec2 = nodevec1\n\n        nodevec1 = torch.tanh(self.alpha*self.lin1(nodevec1))\n        nodevec2 = torch.tanh(self.alpha*self.lin2(nodevec2))\n\n        a = torch.mm(nodevec1, nodevec2.transpose(1,0))\n        adj = F.relu(torch.tanh(self.alpha*a))\n        mask = torch.zeros(idx.size(0), idx.size(0)).to(self.device)\n        mask.fill_(float('0'))\n        s1,t1 = adj.topk(self.k,1)\n        mask.scatter_(1,t1,s1.fill_(1))\n        adj = adj*mask\n        return adj\n\n\nclass LayerNorm(nn.Module):\n    __constants__ = ['normalized_shape', 'weight', 'bias', 'eps', 'elementwise_affine']\n    def __init__(self, normalized_shape, eps=1e-5, elementwise_affine=True):\n        super(LayerNorm, self).__init__()\n        if isinstance(normalized_shape, numbers.Integral):\n            normalized_shape = (normalized_shape,)\n        self.normalized_shape = tuple(normalized_shape)\n        self.eps = eps\n        self.elementwise_affine = elementwise_affine\n        if self.elementwise_affine:\n            self.weight = nn.Parameter(torch.Tensor(*normalized_shape))\n            self.bias = nn.Parameter(torch.Tensor(*normalized_shape))\n        else:\n            self.register_parameter('weight', None)\n            self.register_parameter('bias', None)\n        self.reset_parameters()\n\n\n    def reset_parameters(self):\n        if self.elementwise_affine:\n            init.ones_(self.weight)\n            init.zeros_(self.bias)\n\n    def forward(self, input, idx):\n        if self.elementwise_affine:\n            return F.layer_norm(input, tuple(input.shape[1:]), self.weight[:,idx,:], self.bias[:,idx,:], self.eps)\n        else:\n            return F.layer_norm(input, tuple(input.shape[1:]), self.weight, self.bias, self.eps)\n\n    def extra_repr(self):\n        return '{normalized_shape}, eps={eps}, ' \\\n            'elementwise_affine={elementwise_affine}'.format(**self.__dict__)\n\nclass gtnet(nn.Module):\n    def __init__(self, gcn_true, buildA_true, gcn_depth, num_nodes, device, predefined_A=None, static_feat=None, dropout=0.3, subgraph_size=20, node_dim=40, dilation_exponential=1, conv_channels=32, residual_channels=32, skip_channels=64, end_channels=128, seq_length=12, in_dim=2, out_dim=12, layers=3, propalpha=0.05, tanhalpha=3, layer_norm_affline=True):\n        super(gtnet, self).__init__()\n        self.gcn_true = gcn_true\n        self.buildA_true = buildA_true\n        self.num_nodes = num_nodes\n        self.dropout = dropout\n        self.predefined_A = predefined_A\n        self.filter_convs = nn.ModuleList()\n        self.gate_convs = nn.ModuleList()\n        self.residual_convs = nn.ModuleList()\n        self.skip_convs = nn.ModuleList()\n        self.gconv1 = nn.ModuleList()\n        self.gconv2 = nn.ModuleList()\n        self.norm = nn.ModuleList()\n        self.start_conv = nn.Conv2d(in_channels=in_dim,\n                                    out_channels=residual_channels,\n                                    kernel_size=(1, 1))\n        self.gc = graph_constructor(num_nodes, subgraph_size, node_dim, device, alpha=tanhalpha, static_feat=static_feat)\n\n        self.seq_length = seq_length\n        kernel_size = 7\n        if dilation_exponential>1:\n            self.receptive_field = int(1+(kernel_size-1)*(dilation_exponential**layers-1)/(dilation_exponential-1))\n        else:\n            self.receptive_field = layers*(kernel_size-1) + 1\n\n        for i in range(1):\n            if dilation_exponential>1:\n                rf_size_i = int(1 + i*(kernel_size-1)*(dilation_exponential**layers-1)/(dilation_exponential-1))\n            else:\n                rf_size_i = i*layers*(kernel_size-1)+1\n            new_dilation = 1\n            for j in range(1,layers+1):\n                if dilation_exponential > 1:\n                    rf_size_j = int(rf_size_i + (kernel_size-1)*(dilation_exponential**j-1)/(dilation_exponential-1))\n                else:\n                    rf_size_j = rf_size_i+j*(kernel_size-1)\n\n                self.filter_convs.append(dilated_inception(residual_channels, conv_channels, dilation_factor=new_dilation))\n                self.gate_convs.append(dilated_inception(residual_channels, conv_channels, dilation_factor=new_dilation))\n                self.residual_convs.append(nn.Conv2d(in_channels=conv_channels,\n                                                    out_channels=residual_channels,\n                                                 kernel_size=(1, 1)))\n                if self.seq_length>self.receptive_field:\n                    self.skip_convs.append(nn.Conv2d(in_channels=conv_channels,\n                                                    out_channels=skip_channels,\n                                                    kernel_size=(1, self.seq_length-rf_size_j+1)))\n                else:\n                    self.skip_convs.append(nn.Conv2d(in_channels=conv_channels,\n                                                    out_channels=skip_channels,\n                                                    kernel_size=(1, self.receptive_field-rf_size_j+1)))\n\n                if self.gcn_true:\n                    self.gconv1.append(mixprop(conv_channels, residual_channels, gcn_depth, dropout, propalpha))\n                    self.gconv2.append(mixprop(conv_channels, residual_channels, gcn_depth, dropout, propalpha))\n\n                if self.seq_length>self.receptive_field:\n                    self.norm.append(LayerNorm((residual_channels, num_nodes, self.seq_length - rf_size_j + 1),elementwise_affine=layer_norm_affline))\n                else:\n                    self.norm.append(LayerNorm((residual_channels, num_nodes, self.receptive_field - rf_size_j + 1),elementwise_affine=layer_norm_affline))\n\n                new_dilation *= dilation_exponential\n\n        self.layers = layers\n        self.end_conv_1 = nn.Conv2d(in_channels=skip_channels,\n                                             out_channels=end_channels,\n                                             kernel_size=(1,1),\n                                             bias=True)\n        self.end_conv_2 = nn.Conv2d(in_channels=end_channels,\n                                             out_channels=out_dim,\n                                             kernel_size=(1,1),\n                                             bias=True)\n        if self.seq_length > self.receptive_field:\n            self.skip0 = nn.Conv2d(in_channels=in_dim, out_channels=skip_channels, kernel_size=(1, self.seq_length), bias=True)\n            self.skipE = nn.Conv2d(in_channels=residual_channels, out_channels=skip_channels, kernel_size=(1, self.seq_length-self.receptive_field+1), bias=True)\n\n        else:\n            self.skip0 = nn.Conv2d(in_channels=in_dim, out_channels=skip_channels, kernel_size=(1, self.receptive_field), bias=True)\n            self.skipE = nn.Conv2d(in_channels=residual_channels, out_channels=skip_channels, kernel_size=(1, 1), bias=True)\n\n\n        self.idx = torch.arange(self.num_nodes).to(device)\n\n\n    def forward(self, input, idx=None):\n        seq_len = input.size(3)\n        # pdb.set_trace()\n        assert seq_len==self.seq_length, 'input sequence length not equal to preset sequence length'\n\n        if self.seq_length<self.receptive_field:\n            input = nn.functional.pad(input,(self.receptive_field-self.seq_length,0,0,0))\n\n\n\n        if self.gcn_true:\n            if self.buildA_true:\n                if idx is None:\n                    adp = self.gc(self.idx)\n                else:\n                    adp = self.gc(idx)\n            else:\n                adp = self.predefined_A\n\n        x = self.start_conv(input)\n        skip = self.skip0(F.dropout(input, self.dropout, training=self.training))\n        for i in range(self.layers):\n            residual = x\n            filter = self.filter_convs[i](x)\n            filter = torch.tanh(filter)\n            gate = self.gate_convs[i](x)\n            gate = torch.sigmoid(gate)\n            x = filter * gate\n            x = F.dropout(x, self.dropout, training=self.training)\n            s = x\n            s = self.skip_convs[i](s)\n            skip = s + skip\n            if self.gcn_true:\n                x = self.gconv1[i](x, adp)+self.gconv2[i](x, adp.transpose(1,0))\n            else:\n                x = self.residual_convs[i](x)\n\n            x = x + residual[:, :, :, -x.size(3):]\n            if idx is None:\n                x = self.norm[i](x,self.idx)\n            else:\n                x = self.norm[i](x,idx)\n\n        skip = self.skipE(x) + skip\n        x = F.relu(skip)\n        x = F.relu(self.end_conv_1(x))\n        x = self.end_conv_2(x)\n        return x\n"
  },
  {
    "path": "UCTB/model/STGCN.py",
    "content": "import tensorflow as tf\nimport numpy as np\n\n\ndef build_model(inputs, n_his, Ks, Kt, blocks, keep_prob):\n    \"\"\"\n\n    References:\n        - `Spatio-temporal graph convolutional networks: A deep learning framework for traffic forecasting.\n          <https://www.ijcai.org/proceedings/2018/0505.pdf>`_.\n        - `A Tensorflow implementation of the STGCN model  (VeritasYin)\n          <https://github.com/VeritasYin/STGCN_IJCAI-18>`_.\n\n    Args:\n        inputs: Placeholder.\n        n_his(int): Size of historical records for training.\n        Ks(int): Kernel size of spatial convolution.\n        Kt(int): Kernel size of temporal convolution.\n        blocks(list): Channel configs of st_conv blocks.\n        keep_prob(float): Placeholder.\n    \"\"\"\n    x = inputs[:, 0:n_his, :, :]\n\n    # Ko>0: kernel size of temporal convolution in the output layer.\n    Ko = n_his\n    # ST-Block\n    for i, channels in enumerate(blocks):\n        x = st_conv_block(x, Ks, Kt, channels, i, keep_prob, act_func='GLU')\n        Ko -= 2 * (Ks - 1)\n\n    # Output Layer\n    if Ko > 1:\n        y = output_layer(x, Ko, 'output_layer')\n    else:\n        raise ValueError(f'ERROR: kernel size Ko must be greater than 1, but received \"{Ko}\".')\n\n    tf.add_to_collection(name='copy_loss',\n                         value=tf.nn.l2_loss(inputs[:, n_his - 1:n_his, :, :] - inputs[:, n_his:n_his + 1, :, :]))\n    train_loss = tf.nn.l2_loss(y - inputs[:, n_his:n_his + 1, :, :])\n    single_pred = y[:, 0, :, :]\n    tf.add_to_collection(name='y_pred', value=single_pred)\n    return train_loss, single_pred\n\n\ndef gen_batch(inputs, batch_size, dynamic_batch=False, shuffle=False):\n    '''\n    Data iterator in batch.\n\n    Args:\n        inputs: np.ndarray, [len_seq, n_frame, n_route, C_0], standard sequence units.\n        batch_size: int, the size of batch.\n        dynamic_batch: bool, whether changes the batch size in the last batch if its length is less than the default.\n        shuffle: bool, whether shuffle the batches.\n    '''\n    len_inputs = len(inputs)\n\n    if shuffle:\n        idx = np.arange(len_inputs)\n        np.random.shuffle(idx)\n\n    for start_idx in range(0, len_inputs, batch_size):\n        end_idx = start_idx + batch_size\n        if end_idx > len_inputs:\n            if dynamic_batch:\n                end_idx = len_inputs\n            else:\n                break\n        if shuffle:\n            slide = idx[start_idx:end_idx]\n        else:\n            slide = slice(start_idx, end_idx)\n\n        yield inputs[slide]\n\n\ndef cheb_poly_approx(L, Ks, n):\n    '''\n    Chebyshev polynomials approximation function.\n\n    Args:\n        L: np.matrix, [n_route, n_route], graph Laplacian.\n        Ks: int, kernel size of spatial convolution.\n        n: int, number of routes / size of graph.\n    \n    :return: np.ndarray, [n_route, Ks*n_route].\n    '''\n    L0, L1 = np.mat(np.identity(n)), np.mat(np.copy(L))\n\n    if Ks > 1:\n        L_list = [np.copy(L0), np.copy(L1)]\n        for i in range(Ks - 2):\n            Ln = np.mat(2 * L * L1 - L0)\n            L_list.append(np.copy(Ln))\n            L0, L1 = np.matrix(np.copy(L1)), np.matrix(np.copy(Ln))\n        # L_lsit [Ks, n*n], Lk [n, Ks*n]\n        return np.concatenate(L_list, axis=-1)\n    elif Ks == 1:\n        return np.asarray(L0)\n    else:\n        raise ValueError(f'ERROR: the size of spatial kernel must be greater than 1, but received \"{Ks}\".')\n\n\n\ndef gconv(x, theta, Ks, c_in, c_out):\n    '''\n    Spectral-based graph convolution function.\n        x: tensor, [batch_size, n_route, c_in].\n        theta: tensor, [Ks*c_in, c_out], trainable kernel parameters.\n        Ks: int, kernel size of graph convolution.\n        c_in: int, size of input channel.\n        c_out: int, size of output channel.\n    \n    :return: tensor, [batch_size, n_route, c_out].\n    '''\n    # graph kernel: tensor, [n_route, Ks*n_route]\n    kernel = tf.get_collection('graph_kernel')[0]\n    n = tf.shape(kernel)[0]\n    # x -> [batch_size, c_in, n_route] -> [batch_size*c_in, n_route]\n    x_tmp = tf.reshape(tf.transpose(x, [0, 2, 1]), [-1, n])\n    # x_mul = x_tmp * ker -> [batch_size*c_in, Ks*n_route] -> [batch_size, c_in, Ks, n_route]\n    x_mul = tf.reshape(tf.matmul(x_tmp, kernel), [-1, c_in, Ks, n])\n    # x_ker -> [batch_size, n_route, c_in, K_s] -> [batch_size*n_route, c_in*Ks]\n    x_ker = tf.reshape(tf.transpose(x_mul, [0, 3, 1, 2]), [-1, c_in * Ks])\n    # x_gconv -> [batch_size*n_route, c_out] -> [batch_size, n_route, c_out]\n    x_gconv = tf.reshape(tf.matmul(x_ker, theta), [-1, n, c_out])\n    return x_gconv\n\n\ndef layer_norm(x, scope):\n    '''\n    Layer normalization function.\n    \n    Args:\n        x: tensor, [batch_size, time_step, n_route, channel].\n        scope: str, variable scope.\n    \n    :return: tensor, [batch_size, time_step, n_route, channel].\n    '''\n    _, _, N, C = x.get_shape().as_list()\n    mu, sigma = tf.nn.moments(x, axes=[2, 3], keep_dims=True)\n\n    with tf.variable_scope(scope):\n        gamma = tf.get_variable('gamma', initializer=tf.ones([1, 1, N, C]))\n        beta = tf.get_variable('beta', initializer=tf.zeros([1, 1, N, C]))\n        _x = (x - mu) / tf.sqrt(sigma + 1e-6) * gamma + beta\n    return _x\n\n\ndef temporal_conv_layer(x, Kt, c_in, c_out, act_func='relu'):\n    '''\n    Temporal convolution layer.\n\n    Args:\n        x: tensor, [batch_size, time_step, n_route, c_in].\n        Kt: int, kernel size of temporal convolution.\n        c_in: int, size of input channel.\n        c_out: int, size of output channel.\n        act_func: str, activation function.\n    \n    :return: tensor, [batch_size, time_step-Kt+1, n_route, c_out].\n    '''\n    _, T, n, _ = x.get_shape().as_list()\n\n    if c_in > c_out:\n        w_input = tf.get_variable('wt_input', shape=[1, 1, c_in, c_out], dtype=tf.float32)\n        tf.add_to_collection(name='weight_decay', value=tf.nn.l2_loss(w_input))\n        x_input = tf.nn.conv2d(x, w_input, strides=[1, 1, 1, 1], padding='SAME')\n    elif c_in < c_out:\n        # if the size of input channel is less than the output,\n        # padding x to the same size of output channel.\n        # Note, _.get_shape() cannot convert a partially known TensorShape to a Tensor.\n        x_input = tf.concat([x, tf.zeros([tf.shape(x)[0], T, n, c_out - c_in])], axis=3)\n    else:\n        x_input = x\n\n    # keep the original input for residual connection.\n    x_input = x_input[:, Kt - 1:T, :, :]\n\n    if act_func == 'GLU':\n        # gated liner unit\n        # print(x.shape)\n        wt = tf.get_variable(name='wt', shape=[Kt, 1, c_in, 2 * c_out], dtype=tf.float32)\n        tf.add_to_collection(name='weight_decay', value=tf.nn.l2_loss(wt))\n        bt = tf.get_variable(name='bt', initializer=tf.zeros([2 * c_out]), dtype=tf.float32)\n        x_conv = tf.nn.conv2d(x, wt, strides=[1, 1, 1, 1], padding='VALID') + bt\n        return (x_conv[:, :, :, 0:c_out] + x_input) * tf.nn.sigmoid(x_conv[:, :, :, -c_out:])\n    else:\n        wt = tf.get_variable(name='wt', shape=[Kt, 1, c_in, c_out], dtype=tf.float32)\n        tf.add_to_collection(name='weight_decay', value=tf.nn.l2_loss(wt))\n        bt = tf.get_variable(name='bt', initializer=tf.zeros([c_out]), dtype=tf.float32)\n        x_conv = tf.nn.conv2d(x, wt, strides=[1, 1, 1, 1], padding='VALID') + bt\n        if act_func == 'linear':\n            return x_conv\n        elif act_func == 'sigmoid':\n            return tf.nn.sigmoid(x_conv)\n        elif act_func == 'relu':\n            return tf.nn.relu(x_conv + x_input)\n        else:\n            raise ValueError(f'ERROR: activation function \"{act_func}\" is not defined.')\n\n\ndef spatio_conv_layer(x, Ks, c_in, c_out):\n    '''\n    Spatial graph convolution layer.\n    \n    Args:\n        x: tensor, [batch_size, time_step, n_route, c_in].\n        Ks: int, kernel size of spatial convolution.\n        c_in: int, size of input channel.\n        c_out: int, size of output channel.\n    \n    :return: tensor, [batch_size, time_step, n_route, c_out].\n    '''\n    _, T, n, _ = x.get_shape().as_list()\n\n    if c_in > c_out:\n        # bottleneck down-sampling\n        w_input = tf.get_variable('ws_input', shape=[1, 1, c_in, c_out], dtype=tf.float32)\n        tf.add_to_collection(name='weight_decay', value=tf.nn.l2_loss(w_input))\n        x_input = tf.nn.conv2d(x, w_input, strides=[1, 1, 1, 1], padding='SAME')\n    elif c_in < c_out:\n        # if the size of input channel is less than the output,\n        # padding x to the same size of output channel.\n        # Note, _.get_shape() cannot convert a partially known TensorShape to a Tensor.\n        x_input = tf.concat([x, tf.zeros([tf.shape(x)[0], T, n, c_out - c_in])], axis=3)\n    else:\n        x_input = x\n\n    ws = tf.get_variable(name='ws', shape=[Ks * c_in, c_out], dtype=tf.float32)\n    tf.add_to_collection(name='weight_decay', value=tf.nn.l2_loss(ws))\n    variable_summaries(ws, 'theta')\n    bs = tf.get_variable(name='bs', initializer=tf.zeros([c_out]), dtype=tf.float32)\n    # x -> [batch_size*time_step, n_route, c_in] -> [batch_size*time_step, n_route, c_out]\n    x_gconv = gconv(tf.reshape(x, [-1, n, c_in]), ws, Ks, c_in, c_out) + bs\n    # x_g -> [batch_size, time_step, n_route, c_out]\n    x_gc = tf.reshape(x_gconv, [-1, T, n, c_out])\n    return tf.nn.relu(x_gc[:, :, :, 0:c_out] + x_input)\n\n\ndef st_conv_block(x, Ks, Kt, channels, scope, keep_prob, act_func='GLU'):\n    '''\n    Spatio-temporal convolutional block, which contains two temporal gated convolution layers\n    and one spatial graph convolution layer in the middle.\n\n    Args:\n        x: tensor, batch_size, time_step, n_route, c_in].\n        Ks: int, kernel size of spatial convolution.\n        Kt: int, kernel size of temporal convolution.\n        channels: list, channel configs of a single st_conv block.\n        scope: str, variable scope.\n        keep_prob: placeholder, prob of dropout.\n        act_func: str, activation function.\n    \n    :return: tensor, [batch_size, time_step, n_route, c_out].\n    '''\n    c_si, c_t, c_oo = channels\n\n    with tf.variable_scope(f'stn_block_{scope}_in'):\n        x_s = temporal_conv_layer(x, Kt, c_si, c_t, act_func=act_func)\n        x_t = spatio_conv_layer(x_s, Ks, c_t, c_t)\n    with tf.variable_scope(f'stn_block_{scope}_out'):\n        x_o = temporal_conv_layer(x_t, Kt, c_t, c_oo)\n    x_ln = layer_norm(x_o, f'layer_norm_{scope}')\n    return tf.nn.dropout(x_ln, keep_prob)\n\n\ndef fully_con_layer(x, n, channel, scope):\n    '''\n    Fully connected layer: maps multi-channels to one.\n\n    Args:\n        x: tensor, [batch_size, 1, n_route, channel].\n        n: int, number of route / size of graph.\n        channel: channel size of input x.\n        scope: str, variable scope.\n    \n    :return: tensor, [batch_size, 1, n_route, 1].\n    '''\n    w = tf.get_variable(name=f'w_{scope}', shape=[1, 1, channel, 1], dtype=tf.float32)\n    tf.add_to_collection(name='weight_decay', value=tf.nn.l2_loss(w))\n    b = tf.get_variable(name=f'b_{scope}', initializer=tf.zeros([n, 1]), dtype=tf.float32)\n    return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') + b\n\n\ndef output_layer(x, T, scope, act_func='GLU'):\n    '''\n    Output layer: temporal convolution layers attach with one fully connected layer,\n    which map outputs of the last st_conv block to a single-step prediction.\n\n    Args:\n        x: tensor, [batch_size, time_step, n_route, channel].\n        T: int, kernel size of temporal convolution.\n        scope: str, variable scope.\n        act_func: str, activation function.\n    \n    :return: tensor, [batch_size, 1, n_route, 1].\n    '''\n    _, _, n, channel = x.get_shape().as_list()\n\n    # maps multi-steps to one.\n    with tf.variable_scope(f'{scope}_in'):\n        x_i = temporal_conv_layer(x, T, channel, channel, act_func=act_func)\n    x_ln = layer_norm(x_i, f'layer_norm_{scope}')\n    with tf.variable_scope(f'{scope}_out'):\n        x_o = temporal_conv_layer(x_ln, 1, channel, channel, act_func='sigmoid')\n    # maps multi-channels to one.\n    x_fc = fully_con_layer(x_o, n, channel, scope)\n    return x_fc\n\n\ndef variable_summaries(var, v_name):\n    '''\n    Attach summaries to a Tensor (for TensorBoard visualization).\n    Ref: https://zhuanlan.zhihu.com/p/33178205\n\n    Args:\n        var: tf.Variable().\n        v_name: str, name of the variable.\n    '''\n    with tf.name_scope('summaries'):\n        mean = tf.reduce_mean(var)\n        tf.summary.scalar(f'mean_{v_name}', mean)\n\n        with tf.name_scope(f'stddev_{v_name}'):\n            stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))\n        tf.summary.scalar(f'stddev_{v_name}', stddev)\n\n        tf.summary.scalar(f'max_{v_name}', tf.reduce_max(var))\n        tf.summary.scalar(f'min_{v_name}', tf.reduce_min(var))\n\n        tf.summary.histogram(f'histogram_{v_name}', var)\n\n"
  },
  {
    "path": "UCTB/model/STMeta.py",
    "content": "import keras\nimport tensorflow as tf\n\nfrom ..model_unit import BaseModel\nfrom ..model_unit import GAL, GCL\nfrom ..model_unit import DCGRUCell\nfrom ..model_unit import GCLSTMCell\n\n\nclass STMeta(BaseModel):\n    \"\"\"\n        Args:\n            num_node(int): Number of nodes in the graph, e.g. number of stations in NYC-Bike dataset.\n            external_dim(int): Dimension of the external feature, e.g. temperature and wind are two dimension.\n            closeness_len(int): The length of closeness data history. The former consecutive ``closeness_len`` time slots\n            of data will be used as closeness history.\n            period_len(int): The length of period data history. The data of exact same time slots in former consecutive\n            ``period_len`` days will be used as period history.\n            trend_len(int): The length of trend data history. The data of exact same time slots in former consecutive\n            ``trend_len`` weeks (every seven days) will be used as trend history.\n            input_dim(int): The dimension of input features. 1 if \"with_tpe\" (data_loader parameters) = False, otherwise 0.\n            num_graph(int): Number of graphs used in STMeta.\n            gcn_k(int): The highest order of Chebyshev Polynomial approximation in GCN.\n            gcn_layers(int): Number of GCN layers.\n            gclstm_layers(int): Number of STRNN layers, it works on all modes of STMeta such as GCLSTM and DCRNN.\n            num_hidden_units(int): Number of hidden units of RNN.\n            num_dense_units(int): Number of dense units.\n            graph_merge_gal_units(int): Number of units in GAL for merging different graph features.\n                Only works when graph_merge='gal'\n            graph_merge_gal_num_heads(int): Number of heads in GAL for merging different graph features.\n                Only works when graph_merge='gal'\n            temporal_merge_gal_units(int): Number of units in GAL for merging different temporal features.\n                Only works when temporal_merge='gal'\n            temporal_merge_gal_num_heads(int): Number of heads in GAL for merging different temporal features.\n                Only works when temporal_merge='gal'\n            st_method(str): must in ['GCLSTM', 'DCRNN', 'GRU', 'LSTM'], which refers to different\n                spatial-temporal modeling methods.\n                'GCLSTM': GCN for modeling spatial feature, LSTM for modeling temporal feature.\n                'DCRNN': Diffusion Convolution for modeling spatial feature, GRU for modeling temporam frature.\n                'GRU': Ignore the spatial, and model the temporal feature using GRU\n                'LSTM': Ignore the spatial, and model the temporal feature using LSTM\n            temporal_merge(str): must in ['gal', 'concat'], refers to different temporal merging methods,\n                'gal': merge using GAL,\n                'concat': merge by concat and dense\n            graph_merge(str): must in ['gal', 'concat'], refers to different graph merging methods,\n                'gal': merge using GAL,\n                'concat': merge by concat and dense\n            output_activation(function): activation function, e.g. tf.nn.tanh\n            lr(float): Learning rate. Default: 1e-5\n            code_version(str): Current version of this model code, which will be used as filename for saving the model\n            model_dir(str): The directory to store model files. Default:'model_dir'.\n            gpu_device(str): To specify the GPU to use. Default: '0'.\n        \"\"\"\n\n    def __init__(self,\n                 num_node,\n                 external_dim,\n                 closeness_len,\n                 period_len,\n                 trend_len,\n                 input_dim=1,\n\n                 # gcn parameters\n                 num_graph=1,\n                 gcn_k=1,\n                 gcn_layers=1,\n                 gclstm_layers=1,\n\n                 # dense units\n                 num_hidden_units=64,\n                 # LSTM units\n                 num_dense_units=32,\n\n                 # merge parameters\n                 graph_merge_gal_units=32,\n                 graph_merge_gal_num_heads=2,\n                 temporal_merge_gal_units=64,\n                 temporal_merge_gal_num_heads=2,\n\n                 # network structure parameters\n                 st_method='GCLSTM',  # gclstm\n                 temporal_merge='gal',  # gal\n                 graph_merge='gal',  # concat\n\n                 output_activation=tf.nn.sigmoid,\n\n                 lr=1e-4,\n                 code_version='STMeta-QuickStart',\n                 model_dir='model_dir',\n                 gpu_device='0', **kwargs):\n\n        super(STMeta, self).__init__(code_version=code_version, model_dir=model_dir, gpu_device=gpu_device)\n\n        self._num_node = num_node\n        self._input_dim = input_dim\n        print(\"self._input_dim\",self._input_dim)\n        self._gcn_k = gcn_k\n        self._gcn_layer = gcn_layers\n        self._graph_merge_gal_units = graph_merge_gal_units\n        self._graph_merge_gal_num_heads = graph_merge_gal_num_heads\n        self._temporal_merge_gal_units = temporal_merge_gal_units\n        self._temporal_merge_gal_num_heads = temporal_merge_gal_num_heads\n        self._gclstm_layers = gclstm_layers\n        self._num_graph = num_graph\n        self._external_dim = external_dim\n        self._output_activation = output_activation\n\n        self._st_method = st_method.upper()\n        self._temporal_merge = temporal_merge\n        self._graph_merge = graph_merge\n\n        self._closeness_len = int(closeness_len)\n        self._period_len = int(period_len)\n        self._trend_len = int(trend_len)\n        self._num_hidden_unit = num_hidden_units\n        self._num_dense_units = num_dense_units\n        self._lr = lr\n    \n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n\n            temporal_features = []\n\n            if self._closeness_len is not None and self._closeness_len > 0:\n                closeness_feature = tf.placeholder(tf.float32, [None, None, self._closeness_len, self._input_dim],\n                                                   name='closeness_feature')\n                self._input['closeness_feature'] = closeness_feature.name\n                temporal_features.append([self._closeness_len, closeness_feature, 'closeness_feature'])\n\n            if self._period_len is not None and self._period_len > 0:\n                period_feature = tf.placeholder(tf.float32, [None, None, self._period_len, self._input_dim],\n                                                name='period_feature')\n                self._input['period_feature'] = period_feature.name\n                temporal_features.append([self._period_len, period_feature, 'period_feature'])\n\n            if self._trend_len is not None and self._trend_len > 0:\n                trend_feature = tf.placeholder(tf.float32, [None, None, self._trend_len, self._input_dim],\n                                               name='trend_feature')\n                self._input['trend_feature'] = trend_feature.name\n                temporal_features.append([self._trend_len, trend_feature, 'trend_feature'])\n\n            if len(temporal_features) > 0:\n                target = tf.placeholder(tf.float32, [None, None, 1], name='target')\n                laplace_matrix = tf.placeholder(tf.float32, [self._num_graph, None, None], name='laplace_matrix')\n                self._input['target'] = target.name\n                self._input['laplace_matrix'] = laplace_matrix.name\n            else:\n                raise ValueError('closeness_len, period_len, trend_len cannot all be zero')\n\n            graph_outputs_list = []\n\n            for graph_index in range(self._num_graph):\n\n                if self._st_method in ['GCLSTM', 'DCRNN', 'GRU', 'LSTM']:\n\n                    outputs_temporal = []\n\n                    for time_step, target_tensor, given_name in temporal_features:\n\n                        if self._st_method == 'GCLSTM':\n\n                            multi_layer_cell = tf.keras.layers.StackedRNNCells(\n                                [GCLSTMCell(units=self._num_hidden_unit, num_node=self._num_node,\n                                            laplacian_matrix=laplace_matrix[graph_index],\n                                            gcn_k=self._gcn_k, gcn_l=self._gcn_layer)\n                                 for _ in range(self._gclstm_layers)])\n\n                            outputs = tf.keras.layers.RNN(multi_layer_cell)(tf.reshape(target_tensor, [-1, time_step, self._input_dim]))\n\n                            st_outputs = tf.reshape(outputs, [-1, 1, self._num_hidden_unit])\n\n                        elif self._st_method == 'DCRNN':\n                        # laplace_matrix will be diffusion_matrix when self._st_method == 'DCRNN'\n\n                            encoding_cells = [DCGRUCell(self._num_hidden_unit, self._input_dim, self._num_graph,\n                                             laplace_matrix,\n                                             max_diffusion_step=self._gcn_k,\n                                             num_node=self._num_node, name=str(graph_index) + given_name) for _ in range(self._gclstm_layers)]\n\n                            encoding_cells = tf.contrib.rnn.MultiRNNCell(encoding_cells, state_is_tuple=True)\n\n                            inputs_unstack = tf.unstack(tf.reshape(target_tensor, [-1, self._num_node, time_step]),\n                                                        axis=-1)\n\n                            outputs, _ = \\\n                                tf.contrib.rnn.static_rnn(encoding_cells, inputs_unstack, dtype=tf.float32)\n\n                            st_outputs = tf.reshape(outputs[-1], [-1, 1, self._num_hidden_unit])\n\n                        elif self._st_method == 'GRU':\n\n                            multi_layer_gru = tf.keras.layers.StackedRNNCells([tf.keras.layers.GRUCell(units=self._num_hidden_unit) for _ in range(self._gclstm_layers)])\n                            \n                            outputs = tf.keras.layers.RNN(multi_layer_gru)(\n                                tf.reshape(target_tensor, [-1, time_step, self._input_dim]))\n                            st_outputs = tf.reshape(outputs, [-1, 1, self._num_hidden_unit])\n\n                        elif self._st_method == 'LSTM':\n\n                            multi_layer_gru = tf.keras.layers.StackedRNNCells([tf.keras.layers.LSTMCell(units=self._num_hidden_unit) for _ in range(self._gclstm_layers)])\n                            \n                            outputs = tf.keras.layers.RNN(multi_layer_gru)(\n                                tf.reshape(target_tensor, [-1, time_step, self._input_dim]))\n                            st_outputs = tf.reshape(outputs, [-1, 1, self._num_hidden_unit])\n\n                        outputs_temporal.append(st_outputs)\n\n                    if self._temporal_merge == 'concat':\n                        \n                        graph_outputs_list.append(tf.concat(outputs_temporal, axis=-1))\n\n                    elif self._temporal_merge == 'gal':\n\n                        _, gal_output = GAL.add_ga_layer_matrix(inputs=tf.concat(outputs_temporal, axis=-2),\n                                                                units=self._temporal_merge_gal_units,\n                                                                num_head=self._temporal_merge_gal_num_heads)\n\n                        graph_outputs_list.append(tf.reduce_mean(gal_output, axis=-2, keepdims=True))\n\n            if self._num_graph > 1:\n\n                if self._graph_merge == 'gal':\n                    # (graph, inputs_name, units, num_head, activation=tf.nn.leaky_relu)\n                    _, gal_output = GAL.add_ga_layer_matrix(inputs=tf.concat(graph_outputs_list, axis=-2),\n                                                            units=self._graph_merge_gal_units,\n                                                            num_head=self._graph_merge_gal_num_heads)\n                    dense_inputs = tf.reduce_mean(gal_output, axis=-2, keepdims=True)\n\n                elif self._graph_merge == 'concat':\n\n                    dense_inputs = tf.concat(graph_outputs_list, axis=-1)\n\n            else:\n\n                dense_inputs = graph_outputs_list[-1]\n\n            dense_inputs = tf.reshape(dense_inputs, [-1, self._num_node, 1, dense_inputs.get_shape()[-1].value])\n\n            dense_inputs = tf.keras.layers.BatchNormalization(axis=-1, name='feature_map')(dense_inputs)\n\n            # external dims\n            if self._external_dim is not None and self._external_dim > 0:\n                external_input = tf.placeholder(tf.float32, [None, self._external_dim])\n                self._input['external_feature'] = external_input.name\n                external_dense = tf.keras.layers.Dense(units=10)(external_input)\n                external_dense = tf.tile(tf.reshape(external_dense, [-1, 1, 1, 10]),\n                                         [1, tf.shape(dense_inputs)[1], tf.shape(dense_inputs)[2], 1])\n                dense_inputs = tf.concat([dense_inputs, external_dense], axis=-1)\n\n            dense_output0 = tf.keras.layers.Dense(units=self._num_dense_units,\n                                                  activation=tf.nn.tanh,\n                                                  use_bias=True,\n                                                  kernel_initializer='glorot_uniform',\n                                                  bias_initializer='zeros',\n                                                  kernel_regularizer=tf.keras.regularizers.l2(0.01),\n                                                  bias_regularizer=tf.keras.regularizers.l2(0.01)\n                                                  )(dense_inputs)\n\n            dense_output1 = tf.keras.layers.Dense(units=self._num_dense_units,\n                                                  activation=tf.nn.tanh,\n                                                  use_bias=True,\n                                                  kernel_initializer='glorot_uniform',\n                                                  bias_initializer='zeros',\n                                                  kernel_regularizer=tf.keras.regularizers.l2(0.01),\n                                                  bias_regularizer=tf.keras.regularizers.l2(0.01)\n                                                  )(dense_output0)\n\n            pre_output = tf.keras.layers.Dense(units=1,\n                                               activation=tf.nn.tanh,\n                                               use_bias=True,\n                                               kernel_initializer='glorot_uniform',\n                                               bias_initializer='zeros',\n                                               kernel_regularizer=tf.keras.regularizers.l2(0.01),\n                                               bias_regularizer=tf.keras.regularizers.l2(0.01)\n                                               )(dense_output1)\n\n            prediction = tf.reshape(pre_output, [-1, self._num_node, 1], name='prediction')\n\n            loss_pre = tf.sqrt(tf.reduce_mean(tf.square(target - prediction)), name='loss')\n\n            train_op = tf.train.AdamOptimizer(self._lr).minimize(loss_pre, name='train_op')\n\n            # record output\n            self._output['prediction'] = prediction.name\n            self._output['loss'] = loss_pre.name\n\n            # record train operation\n            self._op['train_op'] = train_op.name\n\n        super(STMeta, self).build(init_vars, max_to_keep)\n\n    # Define your '_get_feed_dict function‘, map your input to the tf-model\n    def _get_feed_dict(self,\n                       laplace_matrix,\n                       closeness_feature=None,\n                       period_feature=None,\n                       trend_feature=None,\n                       target=None,\n                       external_feature=None):\n        feed_dict = {\n            'laplace_matrix': laplace_matrix,\n        }\n        if target is not None:\n            feed_dict['target'] = target\n        if self._external_dim is not None and self._external_dim > 0:\n            feed_dict['external_feature'] = external_feature\n        if self._closeness_len is not None and self._closeness_len > 0:\n            feed_dict['closeness_feature'] = closeness_feature\n        if self._period_len is not None and self._period_len > 0:\n            feed_dict['period_feature'] = period_feature\n        if self._trend_len is not None and self._trend_len > 0:\n            feed_dict['trend_feature'] = trend_feature\n        return feed_dict\n"
  },
  {
    "path": "UCTB/model/STSGCN.py",
    "content": "import numpy as np\nimport mxnet as mx\nfrom UCTB.train.LossFunction import huber_loss\n\n\ndef position_embedding(data,\n                       input_length, num_of_vertices, embedding_size,\n                       temporal=True, spatial=True,\n                       init=mx.init.Xavier(magnitude=0.0003), prefix=\"\"):\n    '''\n    Parameters\n    ----------\n    data: mx.sym.var, shape is (B, T, N, C)\n\n    input_length: int, length of time series, T\n\n    num_of_vertices: int, N\n\n    embedding_size: int, C\n\n    temporal, spatial: bool, whether equip this type of embeddings\n\n    init: mx.initializer.Initializer\n\n    prefix: str\n\n    Returns\n    ----------\n    data: output shape is (B, T, N, C)\n    '''\n\n    temporal_emb = None\n    spatial_emb = None\n\n    if temporal:\n        # shape is (1, T, 1, C)\n        temporal_emb = mx.sym.var(\n            \"{}_t_emb\".format(prefix),\n            shape=(1, input_length, 1, embedding_size),\n            init=init\n        )\n    if spatial:\n        # shape is (1, 1, N, C)\n        spatial_emb = mx.sym.var(\n            \"{}_v_emb\".format(prefix),\n            shape=(1, 1, num_of_vertices, embedding_size),\n            init=init\n        )\n\n    if temporal_emb is not None:\n        data = mx.sym.broadcast_add(data, temporal_emb)\n    if spatial_emb is not None:\n        data = mx.sym.broadcast_add(data, spatial_emb)\n\n    return data\n\n\ndef gcn_operation(data, adj,\n                  num_of_filter, num_of_features, num_of_vertices,\n                  activation, prefix=\"\"):\n    '''\n    graph convolutional operation, a simple GCN we defined in paper\n\n    Parameters\n    ----------\n    data: mx.sym.var, shape is (3N, B, C)\n\n    adj: mx.sym.var, shape is (3N, 3N)\n\n    num_of_filter: int, C'\n\n    num_of_features: int, C\n\n    num_of_vertices: int, N\n\n    activation: str, {'GLU', 'relu'}\n\n    prefix: str\n\n    Returns\n    ----------\n    output shape is (3N, B, C')\n\n    '''\n\n    assert activation in {'GLU', 'relu'}\n\n    # shape is (3N, B, C)\n    data = mx.sym.dot(adj, data)\n\n    if activation == 'GLU':\n\n        # shape is (3N, B, 2C')\n        data = mx.sym.FullyConnected(\n            data,\n            flatten=False,\n            num_hidden=2 * num_of_filter\n        )\n\n        # shape is (3N, B, C'), (3N, B, C')\n        lhs, rhs = mx.sym.split(data, num_outputs=2, axis=2)\n\n        # shape is (3N, B, C')\n        return lhs * mx.sym.sigmoid(rhs)\n\n    elif activation == 'relu':\n\n        # shape is (3N, B, C')\n        return mx.sym.Activation(\n            mx.sym.FullyConnected(\n                data,\n                flatten=False,\n                num_hidden=num_of_filter\n            ), activation\n        )\n\n\ndef stsgcm(data, adj,\n           filters, num_of_features, num_of_vertices,\n           activation, prefix=\"\"):\n    '''\n    STSGCM, multiple stacked gcn layers with cropping and max operation\n\n    Parameters\n    ----------\n    data: mx.sym.var, shape is (3N, B, C)\n\n    adj: mx.sym.var, shape is (3N, 3N)\n\n    filters: list[int], list of C'\n\n    num_of_features: int, C\n\n    num_of_vertices: int, N\n\n    activation: str, {'GLU', 'relu'}\n\n    prefix: str\n\n    Returns\n    ----------\n    output shape is (N, B, C')\n\n    '''\n    need_concat = []\n\n    for i in range(len(filters)):\n        data = gcn_operation(\n            data, adj,\n            filters[i], num_of_features, num_of_vertices,\n            activation=activation,\n            prefix=\"{}_gcn_{}\".format(prefix, i)\n        )\n        need_concat.append(data)\n        num_of_features = filters[i]\n\n    # shape of each element is (1, N, B, C')\n    need_concat = [\n        mx.sym.expand_dims(\n            mx.sym.slice(\n                i,\n                begin=(num_of_vertices, None, None),\n                end=(2 * num_of_vertices, None, None)\n            ), 0\n        ) for i in need_concat\n    ]\n\n    # shape is (N, B, C')\n    return mx.sym.max(mx.sym.concat(*need_concat, dim=0), axis=0)\n\n\ndef stsgcl(data, adj,\n           T, num_of_vertices, num_of_features, filters,\n           module_type, activation, temporal_emb=True, spatial_emb=True,\n           prefix=\"\"):\n    '''\n    STSGCL\n\n    Parameters\n    ----------\n    data: mx.sym.var, shape is (B, T, N, C)\n\n    adj: mx.sym.var, shape is (3N, 3N)\n\n    T: int, length of time series, T\n\n    num_of_vertices: int, N\n\n    num_of_features: int, C\n\n    filters: list[int], list of C'\n\n    module_type: str, {'sharing', 'individual'}\n\n    activation: str, {'GLU', 'relu'}\n\n    temporal_emb, spatial_emb: bool\n\n    prefix: str\n\n    Returns\n    ----------\n    output shape is (B, T-2, N, C')\n    '''\n\n    assert module_type in {'sharing', 'individual'}\n\n    if module_type == 'individual':\n        return sthgcn_layer_individual(\n            data, adj,\n            T, num_of_vertices, num_of_features, filters,\n            activation, temporal_emb, spatial_emb, prefix\n        )\n    else:\n        return sthgcn_layer_sharing(\n            data, adj,\n            T, num_of_vertices, num_of_features, filters,\n            activation, temporal_emb, spatial_emb, prefix\n        )\n\n\ndef sthgcn_layer_individual(data, adj,\n                            T, num_of_vertices, num_of_features, filters,\n                            activation, temporal_emb=True, spatial_emb=True,\n                            prefix=\"\"):\n    '''\n    STSGCL, multiple individual STSGCMs\n\n    Parameters\n    ----------\n    data: mx.sym.var, shape is (B, T, N, C)\n\n    adj: mx.sym.var, shape is (3N, 3N)\n\n    T: int, length of time series, T\n\n    num_of_vertices: int, N\n\n    num_of_features: int, C\n\n    filters: list[int], list of C'\n\n    activation: str, {'GLU', 'relu'}\n\n    temporal_emb, spatial_emb: bool\n\n    prefix: str\n\n    Returns\n    ----------\n    output shape is (B, T-2, N, C')\n    '''\n\n    # shape is (B, T, N, C)\n    data = position_embedding(data, T, num_of_vertices, num_of_features,\n                              temporal_emb, spatial_emb,\n                              prefix=\"{}_emb\".format(prefix))\n    need_concat = []\n    for i in range(T - 2):\n\n        # shape is (B, 3, N, C)\n        t = mx.sym.slice(data, begin=(None, i, None, None),\n                         end=(None, i + 3, None, None))\n\n        # shape is (B, 3N, C)\n        t = mx.sym.reshape(t, (-1, 3 * num_of_vertices, num_of_features))\n\n        # shape is (3N, B, C)\n        t = mx.sym.transpose(t, (1, 0, 2))\n\n        # shape is (N, B, C')\n        t = stsgcm(\n            t, adj, filters, num_of_features, num_of_vertices,\n            activation=activation,\n            prefix=\"{}_stsgcm_{}\".format(prefix, i)\n        )\n\n        # shape is (B, N, C')\n        t = mx.sym.swapaxes(t, 0, 1)\n\n        # shape is (B, 1, N, C')\n        need_concat.append(mx.sym.expand_dims(t, axis=1))\n\n    # shape is (B, T-2, N, C')\n    return mx.sym.concat(*need_concat, dim=1)\n\n\ndef sthgcn_layer_sharing(data, adj,\n                         T, num_of_vertices, num_of_features, filters,\n                         activation, temporal_emb=True, spatial_emb=True,\n                         prefix=\"\"):\n    '''\n    STSGCL, multiple a sharing STSGCM\n\n    Parameters\n    ----------\n    data: mx.sym.var, shape is (B, T, N, C)\n\n    adj: mx.sym.var, shape is (3N, 3N)\n\n    T: int, length of time series, T\n\n    num_of_vertices: int, N\n\n    num_of_features: int, C\n\n    filters: list[int], list of C'\n\n    activation: str, {'GLU', 'relu'}\n\n    temporal_emb, spatial_emb: bool\n\n    prefix: str\n\n    Returns\n    ----------\n    output shape is (B, T-2, N, C')\n    '''\n\n    # shape is (B, T, N, C)\n    data = position_embedding(data, T, num_of_vertices, num_of_features,\n                              temporal_emb, spatial_emb,\n                              prefix=\"{}_emb\".format(prefix))\n    need_concat = []\n    for i in range(T - 2):\n        # shape is (B, 3, N, C)\n        t = mx.sym.slice(data, begin=(None, i, None, None),\n                         end=(None, i + 3, None, None))\n\n        # shape is (B, 3N, C)\n        t = mx.sym.reshape(t, (-1, 3 * num_of_vertices, num_of_features))\n\n        # shape is (3N, B, C)\n        t = mx.sym.swapaxes(t, 0, 1)\n        need_concat.append(t)\n\n    # shape is (3N, (T-2)*B, C)\n    t = mx.sym.concat(*need_concat, dim=1)\n\n    # shape is (N, (T-2)*B, C')\n    t = stsgcm(\n        t, adj, filters, num_of_features, num_of_vertices,\n        activation=activation,\n        prefix=\"{}_stsgcm\".format(prefix)\n    )\n\n    # shape is (N, T - 2, B, C)\n    t = t.reshape((num_of_vertices, T - 2, -1, filters[-1]))\n\n    # shape is (B, T - 2, N, C)\n    return mx.sym.swapaxes(t, 0, 2)\n\n\ndef output_layer(data, num_of_vertices, input_length, num_of_features,\n                 num_of_filters=128, predict_length=12):\n    '''\n    Parameters\n    ----------\n    data: mx.sym.var, shape is (B, T, N, C)\n\n    num_of_vertices: int, N\n\n    input_length: int, length of time series, T\n\n    num_of_features: int, C\n\n    num_of_filters: int, C'\n\n    predict_length: int, length of predicted time series, T'\n\n    Returns\n    ----------\n    output shape is (B, T', N)\n    '''\n\n    # data shape is (B, N, T, C)\n    data = mx.sym.swapaxes(data, 1, 2)\n\n    # (B, N, T * C)\n    data = mx.sym.reshape(\n        data, (-1, num_of_vertices, input_length * num_of_features)\n    )\n\n    # (B, N, C')\n    data = mx.sym.Activation(\n        mx.sym.FullyConnected(\n            data,\n            flatten=False,\n            num_hidden=num_of_filters\n        ), 'relu'\n    )\n\n    # (B, N, T')\n    data = mx.sym.FullyConnected(\n        data,\n        flatten=False,\n        num_hidden=predict_length\n    )\n\n    # (B, T', N)\n    data = mx.sym.swapaxes(data, 1, 2)\n\n    return data\n\n\n\n\n\ndef stsgcn(data, adj, label,\n           input_length, num_of_vertices, num_of_features,\n           filter_list, module_type, activation,\n           use_mask=True, mask_init_value=None,\n           temporal_emb=True, spatial_emb=True,\n           prefix=\"\", rho=1, predict_length=12):\n    \"\"\"\n\n    References:\n        - `Spatial-temporal synchronous graph convolutional networks: A new framework for spatial-temporal network data forecasting.\n          <https://ojs.aaai.org/index.php/AAAI/article/view/5438>`_.\n        - `A Mxnet implementation of the stsgcn model  (Davidham3)\n          <https://github.com/Davidham3/STSGCN>`_.\n\n    Args:\n        data(mxnet.sym): Input data.\n        adj(mxnet.sym): Adjacent matrix.\n        label(mxnet.sym): Prediction label.\n        input_length(int): Length of input data.\n        num_of_vertices(int): Number of vertices in the graph.\n        num_of_features(int): Number of features of each vertice.\n        filter_list(list): Filters.\n        module_type(str): Whether sharing weights.\n        activation(str): Choose which activate function.\n        use_mask(bool): Whether we use mask.\n        mask_init_value(int): Initial value of mask.\n        temporal_emb(bool): Whether to use temporal embedding.\n        spatial_emb(bool): Whether to use spatial embedding.\n        prefix(str): String prefix of mask.\n        rho(float): Hyperparameters used to calculate huber loss.\n        predict_length(int): Length of prediction.\n    \"\"\"\n    '''\n    data shape is (B, T, N, C)\n    adj shape is (3N, 3N)\n    label shape is (B, T, N)\n    '''\n    if use_mask:\n        if mask_init_value is None:\n            raise ValueError(\"mask init value is None!\")\n        mask = mx.sym.var(\"{}_mask\".format(prefix),\n                          shape=(3 * num_of_vertices, 3 * num_of_vertices),\n                          init=mask_init_value)\n        adj = mask * adj\n\n    for idx, filters in enumerate(filter_list):\n        data = stsgcl(data, adj, input_length, num_of_vertices,\n                      num_of_features, filters, module_type,\n                      activation=activation,\n                      temporal_emb=temporal_emb,\n                      spatial_emb=spatial_emb,\n                      prefix=\"{}_stsgcl_{}\".format(prefix, idx))\n        input_length -= 2\n        num_of_features = filters[-1]\n\n    # (B, 1, N)\n    need_concat = []\n    for i in range(predict_length):\n        need_concat.append(\n            output_layer(\n                data, num_of_vertices, input_length, num_of_features,\n                num_of_filters=128, predict_length=1\n            )\n        )\n    data = mx.sym.concat(*need_concat, dim=1)\n\n    loss = huber_loss(data, label, rho=rho)\n    return mx.sym.Group([loss, mx.sym.BlockGrad(data, name='pred')])\n\n\n\ndef construct_model(config, AM):\n\n    module_type = config['module_type']\n    act_type = config['act_type']\n    temporal_emb = config['temporal_emb']\n    spatial_emb = config['spatial_emb']\n    use_mask = config['use_mask']\n    batch_size = config['batch_size']\n\n    num_of_vertices = config['num_of_vertices']\n    num_of_features = config['num_of_features']\n    points_per_hour = config['points_per_hour']\n    num_for_predict = config['num_for_predict']\n\n    adj = AM\n    # print(\"Adj:\",adj.shape,adj)\n    adj_mx = construct_adj(adj, 3)\n    print(\"The shape of localized adjacency matrix: {}\".format(\n        adj_mx.shape), flush=True)\n\n    data = mx.sym.var(\"data\")\n    label = mx.sym.var(\"label\")\n    adj = mx.sym.Variable('adj', shape=adj_mx.shape,\n                          init=mx.init.Constant(value=adj_mx.tolist()))\n    adj = mx.sym.BlockGrad(adj)\n    mask_init_value = mx.init.Constant(value=(adj_mx != 0)\n                                       .astype('float32').tolist())\n\n    filters = config['filters']\n    first_layer_embedding_size = config['first_layer_embedding_size']\n    if first_layer_embedding_size:\n        data = mx.sym.Activation(\n            mx.sym.FullyConnected(\n                data,\n                flatten=False,\n                num_hidden=first_layer_embedding_size\n            ),\n            act_type='relu'\n        )\n    else:\n        first_layer_embedding_size = num_of_features\n    net = stsgcn(\n        data, adj, label,\n        points_per_hour, num_of_vertices, first_layer_embedding_size,\n        filters, module_type, act_type,\n        use_mask, mask_init_value, temporal_emb, spatial_emb,\n        prefix=\"\", rho=1, predict_length=1\n    )\n\n    assert net.infer_shape(\n        data=(batch_size, points_per_hour, num_of_vertices, 1),\n        label=(batch_size, num_for_predict, num_of_vertices)\n    )[1][1] == (batch_size, num_for_predict, num_of_vertices)\n    return net\n\n\n\n\ndef get_adjacency_matrix(distance_df_filename, num_of_vertices,\n                         type_='connectivity', id_filename=None):\n    '''\n    Parameters\n    ----------\n    distance_df_filename: str, path of the csv file contains edges information\n\n    num_of_vertices: int, the number of vertices\n\n    type_: str, {connectivity, distance}\n\n    Returns\n    ----------\n    A: np.ndarray, adjacency matrix\n\n    '''\n    import csv\n\n    A = np.zeros((int(num_of_vertices), int(num_of_vertices)),\n                 dtype=np.float32)\n\n    if id_filename:\n        with open(id_filename, 'r') as f:\n            id_dict = {int(i): idx\n                       for idx, i in enumerate(f.read().strip().split('\\n'))}\n        with open(distance_df_filename, 'r') as f:\n            f.readline()\n            reader = csv.reader(f)\n            for row in reader:\n                if len(row) != 3:\n                    continue\n                i, j, distance = int(row[0]), int(row[1]), float(row[2])\n                A[id_dict[i], id_dict[j]] = 1\n                A[id_dict[j], id_dict[i]] = 1\n        return A\n\n    # Fills cells in the matrix with distances.\n    with open(distance_df_filename, 'r') as f:\n        f.readline()\n        reader = csv.reader(f)\n        for row in reader:\n            if len(row) != 3:\n                continue\n            i, j, distance = int(row[0]), int(row[1]), float(row[2])\n            if type_ == 'connectivity':\n                A[i, j] = 1\n                A[j, i] = 1\n            elif type == 'distance':\n                A[i, j] = 1 / distance\n                A[j, i] = 1 / distance\n            else:\n                raise ValueError(\"type_ error, must be \"\n                                 \"connectivity or distance!\")\n    return A\n\n\ndef construct_adj(A, steps):\n    '''\n    construct a bigger adjacency matrix using the given matrix\n\n    Parameters\n    ----------\n    A: np.ndarray, adjacency matrix, shape is (N, N)\n\n    steps: how many times of the does the new adj mx bigger than A\n\n    Returns\n    ----------\n    new adjacency matrix: csr_matrix, shape is (N * steps, N * steps)\n    '''\n    N = len(A)\n    adj = np.zeros([N * steps] * 2)\n\n    for i in range(steps):\n        adj[i * N: (i + 1) * N, i * N: (i + 1) * N] = A\n\n    for i in range(N):\n        for k in range(steps - 1):\n            adj[k * N + i, (k + 1) * N + i] = 1\n            adj[(k + 1) * N + i, k * N + i] = 1\n\n    for i in range(len(adj)):\n        adj[i, i] = 1\n\n    return adj\n\n\n\n"
  },
  {
    "path": "UCTB/model/ST_MGCN.py",
    "content": "import tensorflow as tf\n\nfrom ..model_unit import BaseModel\nfrom ..model_unit.GraphModelLayers import GCL\n\n\nclass ST_MGCN(BaseModel):\n    \"\"\"\n\n    References:\n        - `Spatiotemporal multi-graph convolution network for ride-hailing demand forecasting (Geng Xu, et al., 2019)\n          <http://www-scf.usc.edu/~yaguang/papers/aaai19_multi_graph_convolution.pdf>`_.\n        - `A PyTorch implementation of the ST-MGCN model  (shawnwang-tech)\n          <https://github.com/shawnwang-tech/ST-MGCN-pytorch>`_.\n\n    Args:\n        T(int): Input sequence length\n        input_dim(int): Input feature dimension\n        num_graph(int): Number of graphs used in the model.\n        gcl_k(int): The highest order of Chebyshev Polynomial approximation in GCN.\n        gcl_l(int): Number of GCN layers.\n        lstm_units(int): Number of hidden units of RNN.\n        lstm_layers(int): Number of LSTM layers.\n        lr(float): Learning rate\n        external_dim(int): Dimension of the external feature, e.g. temperature and wind are two dimension.\n        code_version(str): Current version of this model code, which will be used as filename for saving the model\n        model_dir(str): The directory to store model files. Default:'model_dir'.\n        gpu_device(str): To specify the GPU to use. Default: '0'.\n    \"\"\"\n    def __init__(self,\n                 T,\n                 input_dim,\n                 num_graph,\n                 gcl_k,\n                 gcl_l,\n                 lstm_units,\n                 lstm_layers,\n                 lr,\n                 external_dim,\n                 code_version,\n                 model_dir,\n                 gpu_device):\n\n        super(ST_MGCN, self).__init__(code_version=code_version,\n                                      model_dir=model_dir,\n                                      gpu_device=gpu_device)\n\n        self._T = T\n        self._input_dim = input_dim\n        self._num_graph = num_graph\n        self._gcl_k = gcl_k\n        self._gcl_l = gcl_l\n        self._lstm_units = lstm_units\n        self._lstm_layers = lstm_layers\n        self._lr = lr\n        self._external_dim = external_dim\n\n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            # [batch, T, num_stations, input_dim]\n            traffic_flow = tf.placeholder(tf.float32, [None, self._T, None, self._input_dim])\n            laplacian_matrix = tf.placeholder(tf.float32, [self._num_graph, None, None])\n            target = tf.placeholder(tf.float32, [None, None, 1])\n\n            self._input['traffic_flow'] = traffic_flow.name\n            self._input['laplace_matrix'] = laplacian_matrix.name\n            self._input['target'] = target.name\n\n            station_number = tf.shape(traffic_flow)[-2]\n\n            outputs = []\n\n            for graph_index in range(self._num_graph):\n                with tf.variable_scope('CGRNN_Graph%s' % graph_index, reuse=False):\n                    f_k_g = GCL.add_multi_gc_layers(tf.reshape(traffic_flow, [-1, station_number, self._input_dim]),\n                                                    gcn_k=1, gcn_l=1, output_size=self._input_dim,\n                                                    laplacian_matrix=laplacian_matrix[graph_index],\n                                                    activation=tf.nn.tanh)\n\n                    f_k_g = tf.reshape(f_k_g, [-1, self._T, station_number, self._input_dim])\n\n                    x_hat = tf.concat([f_k_g, traffic_flow], axis=-1)\n\n                    z = tf.reduce_mean(x_hat, axis=-2, keepdims=True)\n\n                    s = tf.layers.dense(tf.layers.dense(z, units=4, use_bias=False, activation=tf.nn.relu),\n                                        units=1, use_bias=False, activation=tf.nn.sigmoid)\n\n                    x_rnn = tf.multiply(traffic_flow, tf.tile(s, [1, 1, station_number, self._input_dim]))\n\n                    x_rnn = tf.reshape(tf.transpose(x_rnn, perm=[0, 2, 1, 3]), [-1, self._T, self._input_dim])\n\n                    for lstm_layer_index in range(self._lstm_layers):\n                        x_rnn = tf.keras.layers.LSTM(units=self._lstm_units,\n                                                     activation='tanh',\n                                                     dropout=0.1,\n                                                     kernel_regularizer=tf.contrib.layers.l2_regularizer(1e-4),\n                                                     return_sequences=True if lstm_layer_index<self._lstm_layers-1\n                                                                      else False)\\\n                                                    (x_rnn)\n\n                    H = tf.reshape(x_rnn, [-1, station_number, self._lstm_units])\n\n                    outputs.append(H)\n\n            outputs = tf.reduce_sum(outputs, axis=0)\n\n            # external dims\n            if self._external_dim is not None and self._external_dim > 0:\n                external_input = tf.placeholder(tf.float32, [None, self._external_dim])\n                self._input['external_feature'] = external_input.name\n                external_dense = tf.layers.dense(inputs=external_input, units=10)\n                external_dense = tf.tile(tf.reshape(external_dense, [-1, 1, 10]),\n                                         [1, tf.shape(outputs)[-2], 1])\n                outputs = tf.concat([outputs, external_dense], axis=-1)\n\n            prediction = tf.layers.dense(outputs, units=1)\n\n            loss = tf.sqrt(tf.reduce_mean(tf.square(prediction - target)))\n\n            train_operation = tf.train.AdamOptimizer(self._lr).minimize(loss, name='train_op')\n\n            # record output\n            self._output['prediction'] = prediction.name\n            self._output['loss'] = loss.name\n\n            # record train operation\n            self._op['train_op'] = train_operation.name\n\n            super(ST_MGCN, self).build(init_vars=init_vars, max_to_keep=max_to_keep)\n\n    # Step 1 : Define your '_get_feed_dict function‘, map your input to the tf-model\n    def _get_feed_dict(self, traffic_flow, laplace_matrix, target=None, external_feature=None):\n        feed_dict = {\n            'traffic_flow': traffic_flow,\n            'laplace_matrix': laplace_matrix,\n        }\n        if target is not None:\n            feed_dict['target'] = target\n        if external_feature is not None:\n            feed_dict['external_feature'] = external_feature\n        return feed_dict\n"
  },
  {
    "path": "UCTB/model/ST_ResNet.py",
    "content": "import tensorflow as tf\r\n\r\nfrom ..model_unit import BaseModel\r\n\r\n\r\nclass ST_ResNet(BaseModel):\r\n    \"\"\"ST-ResNet is a deep-learning model with an end-to-end structure\r\n    based on unique properties of spatio-temporal data making use of convolution and residual units.\r\n\r\n    References:\r\n        - `Deep Spatio-Temporal Residual Networks for Citywide Crowd Flows Prediction (Junbo Zhang et al., 2016)\r\n          <https://arxiv.org/pdf/1610.00081.pdf>`_.\r\n        - `Github repository (lucktroy)\r\n          <https://github.com/lucktroy/DeepST/tree/master/scripts/papers/AAAI17>`_.\r\n    Args:\r\n        width (int): The width of grid data.\r\n        height (int): The height of grid data.\r\n        externai_dim (int): Number of dimensions of external data.\r\n        closeness_len (int): The length of closeness data history. The former consecutive ``closeness_len`` time slots\r\n            of data will be used as closeness history.\r\n        period_len (int): The length of period data history. The data of exact same time slots in former consecutive\r\n            ``period_len`` days will be used as period history.\r\n        trend_len (int): The length of trend data history. The data of exact same time slots in former consecutive\r\n            ``trend_len`` weeks (every seven days) will be used as trend history.\r\n        num_residual_unit (int): Number of residual units. Default: 4\r\n        kernel_size (int): Kernel size in Convolutional neural networks. Default: 3\r\n        lr (float): Learning rate. Default: 1e-5\r\n        code_version (str): Current version of this model code.\r\n        model_dir (str): The directory to store model files. Default:'model_dir'\r\n        conv_filters (int):  the Number of filters in the convolution. Default: 64\r\n        gpu_device (str): To specify the GPU to use. Default: '0'\r\n    \"\"\"\r\n    def __init__(self,\r\n                 width,\r\n                 height,\r\n                 external_dim,\r\n                 closeness_len,\r\n                 period_len,\r\n                 trend_len,\r\n                 num_residual_unit=4,\r\n                 kernel_size=3,\r\n                 lr=5e-5,\r\n                 model_dir='model_dir',\r\n                 code_version='QuickStart',\r\n                 conv_filters=64,\r\n                 gpu_device='0'):\r\n\r\n        super(ST_ResNet, self).__init__(code_version=code_version, model_dir=model_dir, gpu_device=gpu_device)\r\n        \r\n        self._width = width\r\n        self._height = height\r\n        self._closeness_len = closeness_len\r\n        self._period_len = period_len\r\n        self._trend_len = trend_len\r\n        self._conv_filters = conv_filters\r\n        self._kernel_size = kernel_size\r\n        self._external_dim = external_dim\r\n        self._num_residual_unit = num_residual_unit\r\n        self._lr = lr\r\n\r\n    def build(self):\r\n        with self._graph.as_default():\r\n\r\n            target_conf = []\r\n\r\n            if self._closeness_len is not None and self._closeness_len > 0:\r\n                c_conf = tf.placeholder(tf.float32, [None, self._height, self._width, self._closeness_len], name='c')\r\n                self._input['closeness_feature'] = c_conf.name\r\n                target_conf.append(c_conf)\r\n\r\n            if self._period_len is not None and self._period_len > 0:\r\n                p_conf = tf.placeholder(tf.float32, [None, self._height, self._width, self._period_len], name='p')\r\n                self._input['period_feature'] = p_conf.name\r\n                target_conf.append(p_conf)\r\n\r\n            if self._trend_len is not None and self._trend_len > 0:\r\n                t_conf = tf.placeholder(tf.float32, [None, self._height, self._width, self._trend_len], name='t')\r\n                self._input['trend_feature'] = t_conf.name\r\n                target_conf.append(t_conf)\r\n\r\n            target = tf.placeholder(tf.float32, [None, self._height, self._width, 1], name='target')\r\n\r\n            self._input['target'] = target.name\r\n\r\n            outputs = []\r\n            for conf in target_conf:\r\n\r\n                residual_input = tf.layers.conv2d(conf, filters=self._conv_filters,\r\n                                                  kernel_size=[self._kernel_size, self._kernel_size],\r\n                                                  padding='SAME', activation=tf.nn.relu)\r\n\r\n                def residual_unit(x):\r\n                    residual_output = tf.nn.relu(x)\r\n                    residual_output = tf.layers.conv2d(residual_output, filters=self._conv_filters,\r\n                                                       kernel_size=[self._kernel_size, self._kernel_size], padding='SAME')\r\n                    residual_output = tf.nn.relu(residual_output)\r\n                    residual_output = tf.layers.conv2d(residual_output, filters=self._conv_filters,\r\n                                                       kernel_size=[self._kernel_size, self._kernel_size], padding='SAME')\r\n                    return residual_output + x\r\n\r\n                for i in range(self._num_residual_unit):\r\n                    residual_input = residual_unit(residual_input)\r\n\r\n                outputs.append(tf.layers.conv2d(tf.nn.relu(residual_input), filters=self._conv_filters,\r\n                                                kernel_size=[self._kernel_size, self._kernel_size], padding='SAME'))\r\n\r\n            if len(outputs) == 1:\r\n                x = outputs[0]\r\n            else:\r\n                fusion_weight = tf.Variable(tf.random_normal([len(outputs), ]))\r\n                for i in range(len(outputs)):\r\n                    outputs[i] = fusion_weight[i] * outputs[i]\r\n                x = tf.reduce_sum(outputs, axis=0)\r\n\r\n            # external dims\r\n            if self._external_dim is not None and self._external_dim > 0:\r\n                external_input = tf.placeholder(tf.float32, [None, self._external_dim])\r\n                self._input['external_feature'] = external_input.name\r\n                external_dense = tf.layers.dense(inputs=external_input, units=10)\r\n                external_dense = tf.tile(tf.reshape(external_dense, [-1, 1, 1, 10]),\r\n                                         [1, self._height, self._width, 1])\r\n                x = tf.concat([x, external_dense], axis=-1)\r\n\r\n            x = tf.layers.dense(x, units=1, name='prediction', activation=tf.nn.sigmoid)\r\n\r\n            loss = tf.sqrt(tf.reduce_mean(tf.square(x - target)), name='loss')\r\n            train_op = tf.train.AdamOptimizer(self._lr).minimize(loss)\r\n\r\n            self._output['prediction'] = x.name\r\n            self._output['loss'] = loss.name\r\n\r\n            self._op['train_op'] = train_op.name\r\n\r\n        super(ST_ResNet, self).build()\r\n\r\n    def _get_feed_dict(self, closeness_feature=None, period_feature=None, trend_feature=None,\r\n                       target=None, external_feature=None):\r\n        '''\r\n        The method to get feet dict for tensorflow model.\r\n\r\n        Users may modify this method according to the format of input.\r\n\r\n        Args:\r\n            closeness_feature (np.ndarray or ``None``): The closeness history data.\r\n                If type is np.ndarray, its shape is [time_slot_num, height, width, closeness_len].\r\n            period_feature (np.ndarray or ``None``): The period history data.\r\n                If type is np.ndarray, its shape is [time_slot_num, height, width, period_len].\r\n            trend_feature (np.ndarray or ``None``): The trend history data.\r\n                If type is np.ndarray, its shape is [time_slot_num, height, width, trend_len].\r\n            target (np.ndarray or ``None``): The target value data.\r\n                If type is np.ndarray, its shape is [time_slot_num, height, width, 1].\r\n            external_feature (np.ndarray or ``None``): The external feature data.\r\n                If type is np.ndaaray, its shape is [time_slot_num, feature_num].\r\n        '''\r\n        feed_dict = {}\r\n        if target is not None:\r\n            feed_dict['target'] = target\r\n        if self._external_dim is not None and self._external_dim > 0:\r\n            feed_dict['external_feature'] = external_feature\r\n        if self._closeness_len is not None and self._closeness_len > 0:\r\n            feed_dict['closeness_feature'] = closeness_feature\r\n        if self._period_len is not None and self._period_len > 0:\r\n            feed_dict['period_feature'] = period_feature\r\n        if self._trend_len is not None and self._trend_len > 0:\r\n            feed_dict['trend_feature'] = trend_feature\r\n        return feed_dict\r\n"
  },
  {
    "path": "UCTB/model/XGBoost.py",
    "content": "import xgboost as xgb\nimport numpy as np\n\n\nclass XGBoost():\n    \"\"\"\n    XGBoost is an optimized distributed gradient boosting machine learning algorithm.\n\n    Args:\n        *n_estimators (int): Number of boosting iterations. Default: 10\n        *max_depth (int): Maximum tree depth for base learners. Default: 5\n        *verbosity (int): The degree of verbosity. Valid values are 0 (silent) - 3 (debug). Default: 0\n        *objective (string or callable):\n            Specify the learning task and the corresponding learning objective or\n            a custom objective function to be used. Default: ``'reg:squarederror'``\n        *eval_metric (str, list of str, or callable, optional):\n            If a str, should be a built-in evaluation metric to use. See more in\n            `API Reference of XGBoost Library <https://xgboost.readthedocs.io/en/latest/python/python_api.html>`_.\n            Default: ``'rmse'``\n    \"\"\"\n    def __init__(self, n_estimators=10, max_depth=5, verbosity=0, objective='reg:squarederror', eval_metric='rmse'):\n        \n        self.param = {\n            'max_depth': max_depth,\n            'verbosity': verbosity,\n            'objective': objective,\n            'eval_metric': eval_metric\n        }\n        self.n_estimators = n_estimators\n\n    def fit(self, X, y):\n        '''\n        Training method. \n\n        Args:\n            X(np.ndarray/scipy.sparse/pd.DataFrame/dt.Frame): The training input samples.\n            y(np.ndarray, optional): The target values of training samples.\n        '''\n        train_matrix = xgb.DMatrix(X, label=y)\n        self.model = xgb.train(self.param, train_matrix, self.n_estimators)\n\n    def predict(self, X):\n        '''\n        Prediction method.\n        \n        :Returns: Predicted values with shape as [time_slot_num, node_num, 1].\n        :Return type: np.ndarray\n        '''\n        test_matrix = xgb.DMatrix(X)\n        return self.model.predict(test_matrix)\n\n\n"
  },
  {
    "path": "UCTB/model/__init__.py",
    "content": "from .HM import HM\r\nfrom .ARIMA import ARIMA\r\n\r\ntry:\r\n    from .HMM import HMM\r\nexcept ModuleNotFoundError:\r\n    print('HMM not installed')\r\n\r\nfrom .XGBoost import XGBoost\r\n# from .GBRT import GBRT\r\n\r\nfrom .DeepST import DeepST\r\nfrom .ST_ResNet import ST_ResNet\r\n\r\nfrom .STMeta import STMeta\r\n\r\nfrom .DCRNN import DCRNN\r\n\r\nfrom .ST_MGCN import ST_MGCN\r\nfrom .GeoMAN import GeoMAN\r\nfrom .AGCRN import AGCRN\r\nfrom .ASTGCN import make_model\r\nfrom .GMAN import GMAN\r\nfrom .GraphWaveNet import gwnet\r\nfrom .STGCN import build_model\r\nfrom .STSGCN import stsgcn\r\n"
  },
  {
    "path": "UCTB/model_unit/BaseModel.py",
    "content": "import os\r\nimport numpy as np\r\nimport shutil\r\nimport tensorflow as tf\r\n\r\nfrom tensorboard.backend.event_processing import event_accumulator\r\n\r\nfrom ..train.MiniBatchTrain import MiniBatchFeedDict\r\nfrom ..preprocess.preprocessor import SplitData\r\nfrom ..train.EarlyStopping import *\r\n\r\n\r\nclass BaseModel(object):\r\n    \"\"\"BaseModel is the base class for many models, such as STMeta, ST-MGCN and ST_ResNet,\r\n        you can also build your own model using this class. More information can be found in tutorial.\r\n    Args:\r\n        code_version: Current version of this model code, which will be used as filename for saving the model.\r\n        model_dir: The directory to store model files. Default:'model_dir'.\r\n        gpu_device: To specify the GPU to use. Default: '0'.\r\n    \"\"\"\r\n\r\n    def __init__(self, code_version, model_dir, gpu_device):\r\n\r\n        # model input and output\r\n        self._input = {}\r\n        self._output = {}\r\n        self._op = {}\r\n        self._variable_init = None\r\n        self._saver = None\r\n\r\n        self._code_version = code_version\r\n        self._model_dir = model_dir\r\n\r\n        # TF Graph\r\n        self._graph = tf.Graph()\r\n\r\n        self._converged = False\r\n        self._log_dir = os.path.join(self._model_dir, self._code_version)\r\n        self._global_step = 0\r\n        self._summary = None\r\n        self._summary_writer = tf.summary.FileWriter(self._log_dir)\r\n\r\n        self.trainable_vars = 0\r\n\r\n        # TF Session\r\n        self._GPU_DEVICE = gpu_device\r\n        os.environ[\"CUDA_DEVICE_ORDER\"] = \"PCI_BUS_ID\"\r\n        os.environ[\"CUDA_VISIBLE_DEVICES\"] = self._GPU_DEVICE\r\n        self._config = tf.ConfigProto()\r\n        self._config.gpu_options.allow_growth = True\r\n        self._session = tf.Session(graph=self._graph, config=self._config)\r\n\r\n    def build(self, init_vars=True, max_to_keep=5):\r\n        \"\"\"\r\n        Args\r\n            init_vars(bool): auto init the parameters if set to True, else no parameters will be initialized.\r\n            max_to_keep: max file to keep, which equals to max_to_keep in tf.train.Saver.\r\n        \"\"\"\r\n        with self._graph.as_default():\r\n            ####################################################################\r\n            # Add summary, variable_init and summary\r\n            # The variable name of them are fixed\r\n            self.trainable_vars = np.sum([np.prod(v.get_shape().as_list()) for v in tf.trainable_variables()])\r\n            self._saver = tf.train.Saver(max_to_keep=max_to_keep)\r\n            self._variable_init = tf.global_variables_initializer()\r\n            self._summary = self._summary_histogram().name\r\n            ####################################################################\r\n        if init_vars:\r\n            self._session.run(self._variable_init)\r\n\r\n    def add_summary(self, name, value, global_step):\r\n        value_record = tf.Summary(value=[tf.Summary.Value(tag=name, simple_value=value)])\r\n        self._summary_writer.add_summary(value_record, global_step)\r\n\r\n    def _summary_histogram(self):\r\n        with self._graph.as_default():\r\n            for var in tf.trainable_variables():\r\n                tf.summary.histogram(var.name, var)\r\n        self._summary_writer.add_graph(self._graph)\r\n        return tf.summary.merge_all()\r\n\r\n    def _run(self, feed_dict, output_names, op_names):\r\n        feed_dict_tf = {}\r\n        for name, value in feed_dict.items():\r\n            if value is not None:\r\n                feed_dict_tf[self._graph.get_tensor_by_name(self._input[name])] = value\r\n\r\n        output_tensor_list = [self._graph.get_tensor_by_name(self._output[name]) for name in output_names]\r\n        output_tensor_list += [self._graph.get_operation_by_name(self._op[name]) for name in op_names]\r\n\r\n        outputs = self._session.run(output_tensor_list, feed_dict=feed_dict_tf)\r\n\r\n        return {output_names[i]: outputs[i] for i in range(len(output_names))}\r\n\r\n    def _get_feed_dict(self, **kwargs):\r\n        return kwargs\r\n\r\n    def fit(self, sequence_length, output_names=('loss', ), op_names=('train_op', ), evaluate_loss_name='loss',\r\n            batch_size=64, max_epoch=10000, validate_ratio=0.1, shuffle_data=True,\r\n            early_stop_method='t-test', early_stop_length=10, early_stop_patience=0.1,\r\n            verbose=True, save_model=True, save_model_name=None, auto_load_model=True,\r\n            return_outputs=False, **kwargs):\r\n\r\n        \"\"\"\r\n        Args:\r\n            sequence_length: int, the sequence length which is use in mini-batch training\r\n            output_names: list, [output_tensor1_name, output_tensor1_name, ...]\r\n            op_names: list, [operation1_name, operation2_name, ...]\r\n            evaluate_loss_name: str, should be on of the output_names, evaluate_loss_name was use in\r\n                                       early-stopping\r\n            batch_size: int, default 64, batch size\r\n            max_epoch: int, default 10000, max number of epochs\r\n            validate_ratio: float, default 0.1, the ration of data that will be used as validation dataset\r\n            shuffle_data: bool, default True, whether shuffle data in mini-batch train\r\n            early_stop_method: should be 't-test' or 'naive', both method are explained in train.EarlyStopping\r\n            early_stop_length: int, must provide when early_stop_method='t-test'\r\n            early_stop_patience: int, must provide when early_stop_method='naive'\r\n            verbose: Bool, flag to print training information or not\r\n            save_model: Bool, flog to save model or not\r\n            save_model_name: String, filename for saving the model, which will overwrite the code_version.\r\n            auto_load_model: Bool, the \"fit\" function will automatically load the model from disk, if exists,\r\n                before the training. Set to False to disable the auto-loading.\r\n            return_outputs: Bool, set True to return the training log, otherwise nothing will be returned\r\n        \"\"\"\r\n\r\n        if auto_load_model:\r\n            try:\r\n                self.load(self._code_version)\r\n                print('Found model in disk')\r\n                if self._converged:\r\n                    print('Model converged, stop training')\r\n                    return\r\n                else:\r\n                    print('Model not converged, continue at step', self._global_step)\r\n                    start_epoch = self._global_step\r\n            except FileNotFoundError:\r\n                print('No model found, start training')\r\n                start_epoch = 0\r\n        else:\r\n            start_epoch = 0\r\n            print('Not loading model from disk')\r\n\r\n        if not 0 < validate_ratio < 1:\r\n            raise ValueError('validate_ratio should between (0, 1), given', validate_ratio)\r\n\r\n        if evaluate_loss_name not in output_names:\r\n            raise ValueError('evaluate_loss_name not shown in', output_names)\r\n\r\n        if len(op_names) == 0:\r\n            raise ValueError('No operation given')\r\n        else:\r\n            print('Running Operation', op_names)\r\n\r\n        # Get feed_dict\r\n        feed_dict = self._get_feed_dict(**kwargs)\r\n\r\n        # Split data into train-data and validation data\r\n        train_feed_dict, val_feed_dict = SplitData.split_feed_dict(feed_dict,\r\n                                                                   sequence_length=sequence_length,\r\n                                                                   ratio_list=[1 - validate_ratio, validate_ratio])\r\n        train_sequence_length = int(sequence_length*(1-validate_ratio))\r\n        val_sequence_len = sequence_length - train_sequence_length\r\n\r\n        # build mini-batch data source on train-data\r\n        train_dict_mini_batch = MiniBatchFeedDict(feed_dict=train_feed_dict,\r\n                                                  sequence_length=train_sequence_length,\r\n                                                  batch_size=batch_size,\r\n                                                  shuffle=shuffle_data)\r\n\r\n        # record the best result of \"evaluate_loss_name\"\r\n        best_record = None\r\n        # init early stopping object\r\n        if early_stop_method.lower() == 't-test':\r\n            early_stop = EarlyStoppingTTest(length=early_stop_length, p_value_threshold=early_stop_patience)\r\n        else:\r\n            early_stop = EarlyStopping(patience=int(early_stop_patience))\r\n\r\n        # start mini-batch training\r\n        summary_output = []\r\n        for epoch in range(start_epoch, max_epoch):\r\n            train_output_list = []\r\n            for i in range(train_dict_mini_batch.num_batch):\r\n                # train\r\n                train_output = self._run(feed_dict=train_dict_mini_batch.get_batch(),\r\n                                         output_names=output_names,\r\n                                         op_names=op_names)\r\n                train_output_list.append(train_output)\r\n\r\n            # validation\r\n            val_output = self.predict(**val_feed_dict, output_names=output_names,\r\n                                      sequence_length=val_sequence_len,\r\n                                      cache_volume=batch_size)\r\n\r\n            # Here we only care about the evaluate_loss_value\r\n            evaluate_loss_value = np.mean(val_output[evaluate_loss_name])\r\n\r\n            # Add Summary\r\n            tmp_summary = {}\r\n            for name in output_names:\r\n                self.add_summary(name='train_' + name, value=np.mean([e[name] for e in train_output_list]),\r\n                                 global_step=epoch)\r\n                self.add_summary(name='val_' + name, value=np.mean(val_output[name]), global_step=epoch)\r\n                # print training messages\r\n                if verbose:\r\n                    print('Epoch %s:' % epoch,\r\n                          'train_' + name, np.mean([e[name] for e in train_output_list]),\r\n                          'val_' + name, np.mean(val_output[name]))\r\n                    tmp_summary['train_' + name] = np.mean([e[name] for e in train_output_list])\r\n                    tmp_summary['val_' + name] = np.mean(val_output[name])\r\n            summary_output.append(tmp_summary)\r\n\r\n            # manual_summary the histograms\r\n            self.manual_summary(global_step=epoch)\r\n\r\n            if early_stop.stop(evaluate_loss_value):\r\n                if save_model:\r\n                    self._log('Converged')\r\n                break\r\n\r\n            # save the model if evaluate_loss_value is smaller than best_record\r\n            if (best_record is None or evaluate_loss_value < best_record) and save_model:\r\n                best_record = evaluate_loss_value\r\n                self.save(save_model_name or self._code_version, epoch)\r\n\r\n        if return_outputs:\r\n            return summary_output\r\n\r\n    def predict(self, sequence_length, output_names=('prediction', ), cache_volume=64, **kwargs):\r\n\r\n        '''\r\n        Args:\r\n            output_names: list, [output_tensor_name1, output_tensor_name2, ...]\r\n            sequence_length: int, the length of sequence, which is use in mini-batch training\r\n            cache_volume: int, default 64, we need to set cache_volume if the cache can not hold\r\n                                 the whole validation dataset\r\n            :return: outputs_dict: dict, like {output_tensor1_name: output_tensor1_value, ...}\r\n        '''\r\n\r\n        # Get feed_dict\r\n        feed_dict = self._get_feed_dict(**kwargs)\r\n\r\n        if cache_volume and sequence_length:\r\n            # storing the prediction result\r\n            outputs_list = []\r\n            outputs_dict = {}\r\n            for i in range(0, sequence_length, cache_volume):\r\n                tmp_output = self._run({key: value[i:i+cache_volume] if len(value) == sequence_length else value\r\n                                        for key, value in feed_dict.items()},\r\n                                       output_names, op_names=[])\r\n                outputs_list.append(tmp_output)\r\n            # stack the output together\r\n            for key in outputs_list[0]:\r\n                outputs_dict[key] = np.vstack([e[key] for e in outputs_list])\r\n        else:\r\n            outputs_dict = self._run(feed_dict, output_names, op_names=[])\r\n\r\n        return outputs_dict\r\n\r\n    def manual_summary(self, global_step=None):\r\n        self._summary_writer.add_summary(self._session.run(self._graph.get_tensor_by_name(self._summary)),\r\n                                         global_step=global_step)\r\n\r\n    def _log(self, text):\r\n        save_dir_subscript = os.path.join(self._log_dir, self._code_version)\r\n        if os.path.isdir(save_dir_subscript) is False:\r\n            os.makedirs(save_dir_subscript)\r\n        with open(os.path.join(save_dir_subscript, 'log.txt'), 'a+', encoding='utf-8') as f:\r\n            f.write(text + '\\n')\r\n\r\n    def _get_log(self):\r\n        save_dir_subscript = os.path.join(self._log_dir, self._code_version)\r\n        if os.path.isfile(os.path.join(save_dir_subscript, 'log.txt')):\r\n            with open(os.path.join(save_dir_subscript, 'log.txt'), 'r', encoding='utf-8') as f:\r\n                return [e.strip('\\n') for e in f.readlines()]\r\n        else:\r\n            return []\r\n\r\n    def save(self, subscript, global_step):\r\n        \"\"\"\r\n        Args:\r\n            subscript: String, subscript will be appended to the code version as the model filename,\r\n                and save the corresponding model using this filename\r\n            global_step: Int, current training steps\r\n        \"\"\"\r\n        save_dir_subscript = os.path.join(self._log_dir, subscript)\r\n        # delete if exist\r\n        # if os.path.isdir(save_dir_subscript):\r\n        #     shutil.rmtree(save_dir_subscript, ignore_errors=True)\r\n        if os.path.isdir(save_dir_subscript) is False:\r\n            os.makedirs(save_dir_subscript)\r\n        self._saver.save(sess=self._session, save_path=os.path.join(save_dir_subscript, subscript),\r\n                         global_step=global_step)\r\n\r\n    def load(self, subscript):\r\n        \"\"\"\r\n        Args:\r\n            subscript: String, subscript will be appended to the code version as the model file name,\r\n                and load the corresponding model using this filename\r\n        \"\"\"\r\n        save_dir_subscript = os.path.join(self._log_dir, subscript)\r\n        if len(os.listdir(save_dir_subscript)) == 0:\r\n            print('model Not Found')\r\n            raise FileNotFoundError(subscript, 'model not found')\r\n        else:\r\n            meta_file = [e for e in os.listdir(save_dir_subscript) if e.startswith(subscript) and e.endswith('.meta')]\r\n            self._global_step = max([int(e.split('.')[0].split('-')[-1]) for e in meta_file])\r\n            self._saver.restore(sess=self._session,\r\n                                save_path=os.path.join(save_dir_subscript, subscript + '-%s' % self._global_step))\r\n            self._global_step += 1\r\n            # parse the log-file\r\n            log_list = self._get_log()\r\n            for e in log_list:\r\n                if e.lower() == 'converged':\r\n                    self._converged = True\r\n\r\n    def close(self):\r\n        \"\"\"\r\n        Close the session, release memory.\r\n        \"\"\"\r\n        self._session.close()\r\n\r\n    def load_event_scalar(self, scalar_name='val_loss'):\r\n        \"\"\"\r\n        Args:\r\n            scalar_name: load the corresponding scalar name from tensorboard-file,\r\n                e.g. load_event_scalar('val_loss)\r\n        \"\"\"\r\n        event_files = [e for e in os.listdir(self._log_dir) if e.startswith('events.out')]\r\n        result = []\r\n        for f in event_files:\r\n            ea = event_accumulator.EventAccumulator(os.path.join(self._log_dir, f))\r\n            ea.Reload()\r\n            if scalar_name in ea.scalars.Keys():\r\n                result += [[e.wall_time, e.step, e.value] for e in ea.scalars.Items(scalar_name)]\r\n        return result\r\n"
  },
  {
    "path": "UCTB/model_unit/DCRNN_CELL.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\nimport tensorflow as tf\n\nfrom tensorflow.contrib.rnn import RNNCell\n\n\nclass DCGRUCell(RNNCell):\n    \"\"\"Graph Convolution Gated Recurrent Unit cell.\n    \"\"\"\n\n    def call(self, inputs, **kwargs):\n        pass\n\n    def compute_output_shape(self, input_shape):\n        pass\n\n    def __init__(self, num_units, input_dim, num_graphs, supports, max_diffusion_step, num_node, num_proj=None,\n                 activation=tf.nn.tanh, reuse=None, use_gc_for_ru=True, name=None):\n        \"\"\"\n\n        :param num_units:\n        :param adj_mx:\n        :param max_diffusion_step:\n        :param num_node:\n        :param input_size:\n        :param num_proj:\n        :param activation:\n        :param reuse:\n        :param filter_type: \"laplacian\", \"random_walk\", \"dual_random_walk\".\n        :param use_gc_for_ru: whether to use Graph convolution to calculate the reset and update gates.\n        \"\"\"\n        super(DCGRUCell, self).__init__(_reuse=reuse)\n        self._activation = activation\n        self._num_node = num_node\n        self._input_dim = input_dim\n        self._num_graphs = num_graphs\n        self._num_proj = num_proj\n        self._num_units = num_units\n        self._max_diffusion_step = max_diffusion_step\n        self._use_gc_for_ru = use_gc_for_ru\n        self._supports = supports\n        self._num_diff_matrix = supports.get_shape()[0].value\n        self._name = name\n\n    @property\n    def state_size(self):\n        return self._num_node * self._num_units\n\n    @property\n    def output_size(self):\n        output_size = self._num_node * self._num_units\n        if self._num_proj is not None:\n            output_size = self._num_node * self._num_proj\n        return output_size\n\n    def __call__(self, inputs, state, scope=None):\n        \"\"\"Gated recurrent unit (GRU) with Graph Convolution.\n        :param inputs: (B, num_node * input_dim)\n\n        :return\n        - Output: A `2-D` tensor with shape `[batch_size x self.output_size]`.\n        - New state: Either a single `2-D` tensor, or a tuple of tensors matching\n            the arity and shapes of `state`\n        \"\"\"\n        with tf.variable_scope(scope or \"dcgru_cell\"):\n            with tf.variable_scope(\"gates\"):  # Reset gate and update gate.\n                output_size = 2 * self._num_units\n                # We start with bias of 1.0 to not reset and not update.\n                if self._use_gc_for_ru:\n                    fn = self._gconv\n                else:\n                    fn = self._fc\n                value = tf.nn.sigmoid(fn(inputs, state, output_size, bias_start=1.0))\n                value = tf.reshape(value, (-1, self._num_node, output_size))\n                r, u = tf.split(value=value, num_or_size_splits=2, axis=-1)\n                r = tf.reshape(r, (-1, self._num_node * self._num_units))\n                u = tf.reshape(u, (-1, self._num_node * self._num_units))\n            with tf.variable_scope(\"candidate\"):\n                c = self._gconv(inputs, r * state, self._num_units)\n                if self._activation is not None:\n                    c = self._activation(c)\n            output = new_state = u * state + (1 - u) * c\n            if self._num_proj is not None:\n                with tf.variable_scope(\"projection\"):\n                    w = tf.get_variable('w', shape=(self._num_units, self._num_proj))\n                    output = tf.reshape(new_state, shape=(-1, self._num_units))\n                    output = tf.reshape(tf.matmul(output, w), shape=(-1, self.output_size))\n        return output, new_state\n\n    @staticmethod\n    def _concat(x, x_):\n        x_ = tf.expand_dims(x_, 0)\n        return tf.concat([x, x_], axis=0)\n\n    def _fc(self, inputs, state, output_size, bias_start=0.0):\n        dtype = inputs.dtype\n        batch_size = inputs.get_shape()[0].value\n        inputs = tf.reshape(inputs, (batch_size * self._num_node, -1))\n        state = tf.reshape(state, (batch_size * self._num_node, -1))\n        inputs_and_state = tf.concat([inputs, state], axis=-1)\n        input_size = inputs_and_state.get_shape()[-1].value\n        weights = tf.get_variable(\n            'weights', [input_size, output_size], dtype=dtype,\n            initializer=tf.contrib.layers.xavier_initializer())\n        value = tf.nn.sigmoid(tf.matmul(inputs_and_state, weights))\n        biases = tf.get_variable(\"biases\", [output_size], dtype=dtype,\n                                 initializer=tf.constant_initializer(bias_start, dtype=dtype))\n        value = tf.nn.bias_add(value, biases)\n        return value\n\n    def _gconv(self, inputs, state, output_size, bias_start=0.0):\n        \"\"\"Graph convolution between input and the graph matrix.\n\n        :param args: a 2D Tensor or a list of 2D, batch x n, Tensors.\n        :param output_size:\n        :param bias:\n        :param bias_start:\n        :param scope:\n        :return:\n        \"\"\"\n        # Reshape input and state to (batch_size, num_node, input_dim/state_dim)\n        last_dim = inputs.get_shape()[-1].value\n        inputs = tf.reshape(inputs, (-1, self._num_node, int(last_dim / self._num_node)))\n        state = tf.reshape(state, (-1, self._num_node, self._num_units))\n        inputs_and_state = tf.concat([inputs, state], axis=2)\n        input_size = inputs_and_state.get_shape()[2].value\n        dtype = inputs.dtype\n\n        x = inputs_and_state\n        x0 = tf.transpose(x, perm=[1, 2, 0])  # (num_node, total_arg_size, batch_size)\n        x0 = tf.reshape(x0, shape=[self._num_node, -1])\n        x = tf.expand_dims(x0, axis=0)\n\n        scope = tf.get_variable_scope()\n        with tf.variable_scope(scope.name + (self.name or ''), reuse=False):\n            if self._max_diffusion_step == 0:\n                pass\n            else:\n                for index in range(self._num_diff_matrix):\n                    x1 = tf.matmul(self._supports[index], x0)\n                    x = self._concat(x, x1)\n\n                    for k in range(2, self._max_diffusion_step + 1):\n                        x2 = 2 * tf.matmul(self._supports[index], x1) - x0\n                        x = self._concat(x, x2)\n                        x1, x0 = x2, x1\n\n            num_matrices = self._num_diff_matrix * self._max_diffusion_step + 1  # Adds for x itself.\n            x = tf.reshape(x, shape=[num_matrices, self._num_node, input_size, -1])\n            x = tf.transpose(x, perm=[3, 1, 2, 0])  # (batch_size, num_node, input_size, order)\n            x = tf.reshape(x, shape=[-1, input_size * num_matrices])\n\n            weights = tf.get_variable(\n                'weights', [input_size * num_matrices, output_size], dtype=dtype,\n                initializer=tf.contrib.layers.xavier_initializer())\n            x = tf.matmul(x, weights)  # (batch_size * self._num_node, output_size)\n\n            biases = tf.get_variable(\"biases\", [output_size], dtype=dtype,\n                                     initializer=tf.constant_initializer(bias_start, dtype=dtype))\n            x = tf.nn.bias_add(x, biases)\n        # Reshape res back to 2D: (batch_size, num_node, state_dim) -> (batch_size, num_node * state_dim)\n        return tf.reshape(x, [-1, self._num_node * output_size])\n"
  },
  {
    "path": "UCTB/model_unit/GraphModelLayers.py",
    "content": "import numpy as np\r\nimport tensorflow as tf\r\nimport heapq\r\n\r\nfrom math import radians, cos, sin, asin, sqrt\r\nfrom scipy.stats import pearsonr\r\n\r\n# Graph Attention Layer\r\nclass GAL(object):\r\n    '''\r\n    This class provides static methods for adding Graph Attention Layer.\r\n    '''\r\n    @staticmethod\r\n    def attention_merge_weight(inputs, units, num_head, activation=tf.nn.leaky_relu):\r\n        inputs_shape = inputs.get_shape().with_rank(3)\r\n\r\n        num_node = inputs_shape[-2].value\r\n        num_feature = inputs_shape[-1].value\r\n\r\n        W = tf.Variable(tf.random_normal([num_feature, units * num_head]))\r\n\r\n        # linear transform\r\n        l_t = tf.matmul(tf.reshape(inputs, [-1, num_feature]), W)\r\n        l_t = tf.reshape(l_t, [-1, num_node, num_head, units])\r\n\r\n        # compute attention\r\n        a = tf.Variable(tf.random_normal([units * 2, num_head]))\r\n\r\n        e = []\r\n        for j in range(1, num_node):\r\n            multi_head_result = []\r\n            for k in range(num_head):\r\n                multi_head_result.append(tf.matmul(tf.concat([l_t[:, 0, k, :], l_t[:, j, k, :]], axis=-1), a[:, k:k+1]))\r\n            e.append(tf.reshape(tf.concat(multi_head_result, axis=-1), [-1, num_head, 1]))\r\n\r\n        e = activation(tf.reshape(tf.concat(e, axis=-1), [-1, num_head, num_node-1]))\r\n\r\n        alpha = tf.reduce_mean(tf.nn.softmax(e, axis=-1), axis=1, keepdims=True)\r\n\r\n        return alpha\r\n\r\n    @staticmethod\r\n    def add_ga_layer_matrix(inputs, units, num_head, activation=tf.nn.tanh):\r\n        '''\r\n        This method use Multi-head attention technique to add Graph Attention Layer.\r\n\r\n        Args:\r\n            input(ndarray): The set of node features data, with shape [batch, num_node, num_featuer].\r\n            unit(int): The number of merge_gal_units used in GAL.\r\n            num_head(int): The number of multi-head used in GAL.\r\n            activation(function): activation function. default:tf.nn.tanh.\r\n        Returns:\r\n            alpha: The weight matrix after softmax function.\r\n            gc_output: The final GAL aggregated feature representation from input feature.\r\n        '''\r\n        inputs_shape = inputs.get_shape().with_rank(3)\r\n\r\n        num_node = inputs_shape[-2].value\r\n        num_feature = inputs_shape[-1].value\r\n\r\n        W = tf.Variable(tf.random_normal([num_feature, units * num_head], dtype=tf.float32))\r\n\r\n        # linear transform\r\n        l_t = tf.matmul(tf.reshape(inputs, [-1, num_feature]), W)\r\n        l_t = tf.reshape(l_t, [-1, num_node, num_head, units])\r\n\r\n        a = tf.Variable(tf.random_normal([units * 2, num_head], dtype=tf.float32))\r\n\r\n        e_multi_head = []\r\n\r\n        for head_index in range(num_head):\r\n\r\n            l_t_i = l_t[:, :, head_index, :]\r\n            a_i = a[:, head_index:head_index+1]\r\n\r\n            l_t_i_0 = tf.gather(l_t_i, indices=np.array([e for e in range(num_node)] * num_node), axis=1)\r\n            l_t_i_1 = tf.gather(l_t_i, indices=np.array([[e]*num_node for e in range(num_node)]).reshape([-1,]), axis=1)\r\n\r\n            tmp_e = tf.matmul(tf.reshape(tf.concat((l_t_i_0, l_t_i_1), axis=-1), [-1, units*2]), a_i)\r\n            tmp_e = tf.nn.softmax(activation(tf.reshape(tmp_e, [-1, 1, num_node, num_node])), axis=-1)\r\n\r\n            e_multi_head.append(tmp_e)\r\n\r\n        alpha = tf.concat(e_multi_head, axis=1)\r\n\r\n        # Averaging\r\n        gc_output = activation(tf.reduce_mean(tf.matmul(alpha, tf.transpose(l_t, [0, 2, 1, 3])), axis=1))\r\n\r\n        return alpha, gc_output\r\n\r\n    @staticmethod\r\n    def add_residual_ga_layer(inputs, units, num_head, activation=tf.nn.tanh):\r\n        '''\r\n        Call the add_ga_layer_matrix function to build the Graph Attention Layer, \r\n        and add the residual layer to optimize the deep neural network.\r\n        '''\r\n        _, gc_output = GAL.add_ga_layer_matrix(inputs, units, num_head, activation=activation)\r\n\r\n        gc_output_residual = tf.concat([gc_output, inputs], axis=-1)\r\n\r\n        return gc_output_residual\r\n\r\n\r\n# Graph Convolution Layer\r\nclass GCL(object):\r\n    '''\r\n    This class provides static methods for adding Graph Convolution Layer.\r\n    '''\r\n    @staticmethod\r\n    def add_gc_layer(inputs,\r\n                     gcn_k,\r\n                     laplacian_matrix,\r\n                     output_size,\r\n                     dtype=tf.float32,\r\n                     use_bias=True,\r\n                     trainable=True,\r\n                     initializer=None,\r\n                     regularizer=None,\r\n                     activation=tf.nn.tanh):\r\n        '''\r\n        Args:\r\n            Input(ndarray): The input features with shape [batch, num_node, num_feature].\r\n            gcn_k(int): The highest order of Chebyshev Polynomial approximation in GCN.\r\n            laplacian_matrix(ndarray): Laplacian matrix used in GCN, with shape [num_node, num_node].\r\n            output_size(int): Number of output channels.\r\n            dtype: Data type. default:tf.float32.\r\n            use_bias(bool): It determines whether to add bias in the output. default:True.\r\n            trainable(bool): It determines whether `weights` tensor can be trained. default:True.\r\n            initializer: It determines whether the \"weight\" tensor is initialized. default:None.\r\n            regularizer: It determines whether the \"weight\" tensor is regularized. default:None.\r\n            activation(function): activation function. default:tf.nn.tanh.\r\n        Returns:\r\n            Returns the result of convolution of `inputs` and `laplacian_matrix`\r\n        '''\r\n        # [batch_size, num_node, num_feature]\r\n        input_shape = inputs.get_shape().with_rank(3)\r\n\r\n        num_node = tf.shape(inputs)[-2]\r\n        num_feature = input_shape[-1].value\r\n\r\n        # GC on inputs\r\n        # reshape from [batch, num_node, num_feature] into [num_node, batch*num_feature]\r\n        gc_input = tf.reshape(tf.transpose(inputs, perm=[1, 0, 2]), [num_node, -1])\r\n\r\n        # Chebyshev polynomials\r\n        # Reference: https://github.com/mdeff/cnn_graph\r\n        gc_outputs = list()\r\n        # Xt_0 = T_0 X = I X = X.\r\n        gc_outputs.append(gc_input)\r\n        # Xt_1 = T_1 X = L X.\r\n        if gcn_k >= 1:\r\n            gc_outputs.append(tf.matmul(laplacian_matrix, gc_input))\r\n        # Xt_k = 2 L Xt_k-1 - Xt_k-2.\r\n        for k in range(2, gcn_k+1):\r\n            gc_outputs.append(2 * tf.matmul(laplacian_matrix, gc_outputs[-1]) - gc_outputs[-1])\r\n\r\n        # [gcn_k+1, number_nodes, batch*num_feature]\r\n        gc_outputs = tf.reshape(gc_outputs, [gcn_k+1, num_node, -1, num_feature])\r\n        # [batch, number_nodes, num_feature, gcn_k+1]\r\n        gc_outputs = tf.transpose(gc_outputs, [2, 1, 3, 0])\r\n        # [batch*number_nodes, num_feature*gcn_k+1]\r\n        gc_outputs = tf.reshape(gc_outputs, [-1, num_feature*(gcn_k+1)])\r\n\r\n        output_weight = tf.get_variable(\"weights\", shape=[num_feature*(gcn_k+1), output_size],\r\n                                        trainable=trainable, dtype=dtype,\r\n                                        initializer=initializer, regularizer=regularizer)\r\n        gc_outputs = tf.matmul(gc_outputs, output_weight)\r\n\r\n        if use_bias:\r\n            biases = tf.get_variable(\"biases\", [output_size], dtype=dtype,\r\n                                     initializer=tf.constant_initializer(0, dtype=dtype))\r\n            gc_outputs = tf.nn.bias_add(gc_outputs, biases)\r\n\r\n        gc_outputs = tf.reshape(gc_outputs, [-1, num_node, output_size])\r\n\r\n        return activation(gc_outputs)\r\n\r\n    @staticmethod\r\n    def add_multi_gc_layers(inputs, gcn_k, gcn_l, output_size, laplacian_matrix, activation=tf.nn.tanh):\r\n        '''\r\n        Call add_gc_layer function to add multi Graph Convolution Layer.`gcn_l` is the number of layers added.\r\n        '''\r\n        with tf.variable_scope('multi_gcl', reuse=False):\r\n            for i in range(gcn_l):\r\n                with tf.variable_scope('gcl_%s' % i, reuse=False):\r\n                    inputs = GCL.add_gc_layer(inputs=inputs,\r\n                                              gcn_k=gcn_k,\r\n                                              laplacian_matrix=laplacian_matrix,\r\n                                              output_size=output_size,\r\n                                              activation=activation)\r\n        return inputs\r\n"
  },
  {
    "path": "UCTB/model_unit/ST_RNN.py",
    "content": "import tensorflow as tf\n\nfrom tensorflow.python.framework import dtypes\nfrom tensorflow.python.keras import backend as K\nfrom tensorflow.python.keras.utils import tf_utils\nfrom tensorflow.python.ops import array_ops, linalg_ops, math_ops\n\n\ndef _generate_dropout_mask(ones, rate, training=None, count=1):\n    def dropped_inputs():\n        return K.dropout(ones, rate)\n\n    if count > 1:\n        return [\n            K.in_train_phase(dropped_inputs, ones, training=training)\n            for _ in range(count)\n        ]\n    return K.in_train_phase(dropped_inputs, ones, training=training)\n\n\nclass GCLSTMCell(tf.keras.layers.LSTMCell):\n\n    \"\"\"\n    GCLSTMCell is one of our implemented ST-RNN models in handling the spatial and temporal features.\n    We performed GCN on both LSTM inputs and hidden-states. The code is inherited from tf.keras.layers.LSTMCell,\n    thus it can be used almost the same as LSTMCell except that you need to provide the GCN parameters\n    in the __init__ function.\n\n    Args:\n        units(int): number of units of LSTM\n        num_node(int): number of nodes in the graph\n        laplacian_matrix(ndarray): laplacian matrix used in GCN, with shape [num_node, num_node]\n        gcn_k(int): highest order of Chebyshev Polynomial approximation in GCN\n        gcn_l(int): number of GCN layers\n        kwargs: other parameters supported by LSTMCell, such as activation, kernel_initializer ... and so on.\n    \"\"\"\n\n    def __init__(self, units, num_node, laplacian_matrix, gcn_k=1, gcn_l=1, **kwargs):\n\n        super().__init__(units, **kwargs)\n\n        self._units = units\n        self._num_node = num_node\n        self._gcn_k = gcn_k\n        self._gcn_l = gcn_l\n        self._laplacian_matrix = laplacian_matrix\n\n    @tf_utils.shape_type_conversion\n    def build(self, input_shape):\n        super(GCLSTMCell, self).build(input_shape)\n        input_dim = input_shape[-1]\n        self.kernel = self.add_weight(\n            shape=(input_dim * (self._gcn_k + 1), self.units * 4),\n            name='kernel',\n            initializer=self.kernel_initializer,\n            regularizer=self.kernel_regularizer,\n            constraint=self.kernel_constraint)\n        self.recurrent_kernel = self.add_weight(\n            shape=(self.units * (self._gcn_k + 1), self.units * 4),\n            name='recurrent_kernel',\n            initializer=self.recurrent_initializer,\n            regularizer=self.recurrent_regularizer,\n            constraint=self.recurrent_constraint)\n\n    def kth_cheby_ploy(self, k, tk1=None, tk2=None):\n        if k == 0:\n            return linalg_ops.eye(self._num_node, dtype=dtypes.float32)\n        elif k == 1:\n            return self._laplacian_matrix\n        elif k > 1:\n            return math_ops.matmul(2 * self._laplacian_matrix, tk1) - tk2\n\n    def call(self, inputs, states, training=None):\n\n        if 0 < self.dropout < 1 and self._dropout_mask is None:\n            self._dropout_mask = _generate_dropout_mask(\n                array_ops.ones_like(inputs),\n                self.dropout,\n                training=training,\n                count=4)\n        if (0 < self.recurrent_dropout < 1 and\n                self._recurrent_dropout_mask is None):\n            self._recurrent_dropout_mask = _generate_dropout_mask(\n                array_ops.ones_like(states[0]),\n                self.recurrent_dropout,\n                training=training,\n                count=4)\n\n        input_dim = inputs.get_shape()[-1].value\n\n        # dropout matrices for input units\n        dp_mask = self._dropout_mask\n        # dropout matrices for recurrent units\n        rec_dp_mask = self._recurrent_dropout_mask\n\n        h_tm1 = states[0]  # previous memory state\n        c_tm1 = states[1]  # previous carry state\n\n        if 0. < self.dropout < 1.:\n            inputs *= dp_mask[0]\n        if 0. < self.recurrent_dropout < 1.:\n            h_tm1 *= rec_dp_mask[0]\n\n        # inputs has shape: [batch * num_node, input_dim]\n        # h_tm1 has shape: [batch * num_node, units]\n        inputs_before_gcn = tf.reshape(tf.transpose(tf.reshape(inputs, [-1, self._num_node, input_dim]),\n                                                    [1, 0, 2]), [self._num_node, -1])\n        h_tm1_before_gcn = tf.reshape(tf.transpose(tf.reshape(h_tm1, [-1, self._num_node, self._units]),\n                                                   [1, 0, 2]), [self._num_node, -1])\n\n        t = []\n        inputs_after_gcn = list()\n        h_tm1_after_gcn = list()\n        for i in range(0, self._gcn_k + 1):\n            t.append(self.kth_cheby_ploy(k=i, tk1=None if i < 1 else t[i - 1], tk2=None if i < 2 else t[i - 2]))\n            inputs_after_gcn.append(tf.matmul(t[-1], inputs_before_gcn))\n            h_tm1_after_gcn.append(tf.matmul(t[-1], h_tm1_before_gcn))\n\n        inputs_after_gcn = tf.reshape(inputs_after_gcn, [self._gcn_k + 1, self._num_node, -1, input_dim])\n        h_tm1_after_gcn = tf.reshape(h_tm1_after_gcn, [self._gcn_k + 1, self._num_node, -1, self._units])\n\n        inputs_after_gcn = tf.reshape(tf.transpose(inputs_after_gcn, [2, 1, 0, 3]), [-1, (self._gcn_k + 1) * input_dim])\n        h_tm1_after_gcn = tf.reshape(tf.transpose(h_tm1_after_gcn, [2, 1, 0, 3]), [-1, (self._gcn_k + 1) * self.units])\n\n        z = K.dot(inputs_after_gcn, self.kernel)\n        z += K.dot(h_tm1_after_gcn, self.recurrent_kernel)\n        if self.use_bias:\n            z = K.bias_add(z, self.bias)\n\n        z0 = z[:, :self.units]\n        z1 = z[:, self.units:2 * self.units]\n        z2 = z[:, 2 * self.units:3 * self.units]\n        z3 = z[:, 3 * self.units:]\n\n        z = (z0, z1, z2, z3)\n        c, o = self._compute_carry_and_output_fused(z, c_tm1)\n\n        h = o * self.activation(c)\n        return h, [h, c]\n"
  },
  {
    "path": "UCTB/model_unit/__init__.py",
    "content": "\nfrom .BaseModel import BaseModel\n\nfrom .GraphModelLayers import GCL\nfrom .GraphModelLayers import GAL\n\nfrom .DCRNN_CELL import DCGRUCell\nfrom .ST_RNN import GCLSTMCell\n"
  },
  {
    "path": "UCTB/preprocess/GraphGenerator.py",
    "content": "import numpy as np\nimport tensorflow as tf\nimport heapq\n\n# from UCTB.preprocess import Normalizer, SplitData\n\nfrom math import radians, cos, sin, asin, sqrt\nfrom scipy.stats import pearsonr\nfrom scipy.sparse.linalg import eigs\n\nclass GraphGenerator():\n    '''\n    This class is used to build graphs. \n    Adajacent matrix and lapalace matrix will be stored in self.AM and self.LM.\n\n    Args:\n        data_loader(NodeTrafficLoader): data_loader object.\n        graph (str): Types of graphs used in neural methods. Graphs should be a subset of { ``'Correlation'``,\n            ``'Distance'``, ``'Interaction'``, ``'Line'``, ``'Neighbor'``, ``'Transfer'`` } and concatenated by ``'-'``,\n            and *dataset* should have data of selected graphs. Default: ``'Correlation'``\n        threshold_distance (float): Used in building of distance graph. If distance of two nodes in meters is larger\n            than ``threshold_distance``, the corresponding position of the distance graph will be 1 and otherwise\n            0.the corresponding Default: 1000\n        threshold_correlation (float): Used in building of correlation graph. If the Pearson correlation coefficient is\n            larger than ``threshold_correlation``, the corresponding position of the correlation graph will be 1\n            and otherwise 0. Default: 0\n        threshold_interaction (float): Used in building of interatction graph. If in the latest 12 months, the number of\n            times of interaction between two nodes is larger than ``threshold_interaction``, the corresponding position\n            of the interaction graph will be 1 and otherwise 0. Default: 500\n\n    Attributes:\n        AM (array): Adajacent matrices of graphs.\n        LM (array): Laplacian matrices of graphs.\n    '''\n\n    def __init__(self,\n                 data_loader,\n                 graph=\"Correlation\",\n                 threshold_distance=1000,\n                 threshold_correlation=0,\n                 threshold_interaction=500, **kwargs):\n        self.AM = []\n        self.LM = []\n        self.threshold_distance = threshold_distance\n        self.threshold_correlation = threshold_correlation\n        self.threshold_interaction = threshold_interaction\n\n        self.dataset = data_loader.dataset\n        self.train_data = data_loader.train_data\n        self.traffic_data_index = data_loader.traffic_data_index\n        self.train_test_ratio = data_loader.train_test_ratio\n        self.daily_slots = 24 * 60 / self.dataset.time_fitness\n\n        # build_graph\n        for graph_name in graph.split('-'):\n            AM, LM = self.build_graph(graph_name)\n            if AM is not None:\n                self.AM.append(AM)\n            if LM is not None:\n                self.LM.append(LM)\n        \n        self.AM = np.array(self.AM, dtype=np.float32)\n        self.LM = np.array(self.LM, dtype=np.float32)\n        # print (self.LM.shape[:])\n\n    def build_graph(self, graph_name):\n        AM, LM = None, None\n        if graph_name.lower() == 'distance':\n            lat_lng_list = np.array([[float(e1) for e1 in e[2:4]]\n                                     for e in self.dataset.node_station_info])\n            AM = self.distance_adjacent(lat_lng_list[self.traffic_data_index],\n                                                threshold=float(self.threshold_distance))\n            LM = self.adjacent_to_laplacian(AM)\n\n        if graph_name.lower() == 'interaction':\n            monthly_interaction = self.dataset.node_monthly_interaction[:, self.traffic_data_index, :][:, :,\n                                                                                                       self.traffic_data_index]\n\n            monthly_interaction, _ = SplitData.split_data(\n                monthly_interaction, self.train_test_ratio)\n\n            annually_interaction = np.sum(monthly_interaction[-12:], axis=0)\n            annually_interaction = annually_interaction + annually_interaction.transpose()\n\n            AM = self.interaction_adjacent(annually_interaction,\n                                                   threshold=float(self.threshold_interaction))\n            LM = self.adjacent_to_laplacian(AM)\n\n        if graph_name.lower() == 'correlation':\n            AM = self.correlation_adjacent(self.train_data[-30 * int(self.daily_slots):],\n                                                   threshold=float(self.threshold_correlation))\n            LM = self.adjacent_to_laplacian(AM)\n\n        if graph_name.lower() == 'neighbor':\n            LM = self.adjacent_to_laplacian(\n                self.dataset.data.get('contribute_data').get('graph_neighbors'))\n\n        if graph_name.lower() == 'line':\n            LM = self.adjacent_to_laplacian(\n                self.dataset.data.get('contribute_data').get('graph_lines'))\n            LM = LM[self.traffic_data_index]\n            LM = LM[:, self.traffic_data_index]\n\n        if graph_name.lower() == 'transfer':\n            LM = self.adjacent_to_laplacian(\n                self.dataset.data.get('contribute_data').get('graph_transfer'))\n        return AM, LM\n\n    @staticmethod\n    def haversine(lat1, lon1, lat2, lon2):\n        \"\"\"\n        Calculate the great circle distance between two points\n        on the earth (specified in decimal degrees)\n        \"\"\"\n        lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])\n\n        # haversine\n        dlon = lon2 - lon1\n        dlat = lat2 - lat1\n        a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2\n        c = 2 * asin(sqrt(a))\n        r = 6371\n\n        return c * r * 1000\n\n    @staticmethod\n    def correlation_adjacent(traffic_data, threshold):\n        '''\n        Calculate correlation graph based on pearson coefficient.\n\n        Args:\n            traffic_data(ndarray): numpy array with shape [sequence_length, num_node].\n            threshold(float): float between [-1, 1], nodes with Pearson Correlation coefficient\n                larger than this threshold will be linked together.\n        '''\n        adjacent_matrix = np.zeros([traffic_data.shape[1], traffic_data.shape[1]])\n        for i in range(traffic_data.shape[1]):\n            for j in range(traffic_data.shape[1]):\n                r, p_value = pearsonr(traffic_data[:, i], traffic_data[:, j])\n                adjacent_matrix[i, j] = 0 if np.isnan(r) else r\n        adjacent_matrix = (adjacent_matrix >= threshold).astype(np.float32)\n        return adjacent_matrix\n\n    def distance_adjacent(self, lat_lng_list, threshold):\n        '''\n        Calculate distance graph based on geographic distance.\n\n        Args:\n            lat_lng_list(list): A list of geographic locations. The format of each element\n                    in the list is [latitude, longitude].\n            threshold(float): (meters) nodes with geographic distacne smaller than this \n                threshold will be linked together.\n        '''\n        adjacent_matrix = np.zeros([len(lat_lng_list), len(lat_lng_list)])\n        for i in range(len(lat_lng_list)):\n            for j in range(len(lat_lng_list)):\n                adjacent_matrix[i][j] = self.haversine(lat_lng_list[i][0], lat_lng_list[i][1],\n                                                                lat_lng_list[j][0], lat_lng_list[j][1])\n        adjacent_matrix = (adjacent_matrix <= threshold).astype(np.float32)\n        return adjacent_matrix\n\n    @staticmethod\n    def interaction_adjacent(interaction_matrix, threshold):\n        '''\n        Binarize interaction_matrix based on threshold.\n\n        Args:\n\n            interaction_matrix(ndarray): with shape [num_node, num_node], where each \n                element represents the number of interactions during a certain time,\n                    e.g. 6 monthes, between the corresponding nodes.\n            threshold(float or int): nodes with number of interactions between them\n                    greater than this threshold will be linked together.\n        '''\n        return (interaction_matrix >= threshold).astype(np.float32)      \n\n    @staticmethod\n    def adjacent_to_laplacian(adjacent_matrix):\n        '''\n        Turn adjacent_matrix into Laplace matrix.\n        '''\n        adjacent_matrix -= np.diag(np.diag(adjacent_matrix))\n        diagonal_matrix = np.diag(np.sum(adjacent_matrix, axis=0) ** -0.5)\n        diagonal_matrix[np.isinf(diagonal_matrix)] = 0\n        laplacian_matrix = np.eye(len(adjacent_matrix)) - np.dot(np.dot(diagonal_matrix, adjacent_matrix),\n                                                                    diagonal_matrix)\n        laplacian_matrix = 2 * laplacian_matrix / np.max(laplacian_matrix) - np.eye(len(adjacent_matrix))\n        return laplacian_matrix\n\n\n\ndef scaled_Laplacian_ASTGCN(W):\n    '''\n    compute \\tilde{L}\n\n    Parameters\n    ----------\n    W(np.ndarray): shape is (num_node, num_node).\n\n    Returns\n    ----------\n    scaled_Laplacian_ASTGCN: np.ndarray, shape (num_node, num_node)\n\n    '''\n\n    assert W.shape[0] == W.shape[1]\n\n    D = np.diag(np.sum(W, axis=1))\n\n    L = D - W\n\n    lambda_max = eigs(L, k=1, which='LR')[0].real\n\n    return (2 * L) / lambda_max - np.identity(W.shape[0])\n\n\ndef scaled_laplacian_STGCN(W):\n    '''\n    Normalized graph Laplacian function.\n\n    Args:\n        W(np.ndarray): [num_node, num_node], weighted adjacency matrix of G.\n    :return: Scaled laplacian matrix.\n    :type: np.matrix, [num_node, num_node].\n    '''\n    # d ->  diagonal degree matrix\n    n, d = np.shape(W)[0], np.sum(W, axis=1)\n    # L -> graph Laplacian\n    L = -W\n    L[np.diag_indices_from(L)] = d\n    for i in range(n):\n        for j in range(n):\n            if (d[i] > 0) and (d[j] > 0):\n                L[i, j] = L[i, j] / np.sqrt(d[i] * d[j])\n    # lambda_max \\approx 2.0, the largest eigenvalues of L.\n    lambda_max = eigs(L, k=1, which='LR')[0][0].real\n    return np.mat(2 * L / lambda_max - np.identity(n))\n"
  },
  {
    "path": "UCTB/preprocess/RegionGenerator.py",
    "content": "import logging\nimport numpy as np\ndef grid_partition():\n    # To be implemented\n    pass\n\ndef hexagon_partition():\n    # To be implemented\n    pass\n\ndef roadnetwork_partition():\n    # To be implemented\n    pass\n\ndef location_bind():\n    # To be implemented\n    pass\n\ndef async_fluid():\n    # To be implemented\n    pass\n\ndef node_swapping():\n    # To be implemented\n    pass\n\nclass RegionGenerator():\n    '''\n    This class is used to generate regions and create demand matrix.\n    Regions will be stored into self.regions and demand matrix will be stored into self.demand_matrix\n    This class should be instantiated before NodeTrafficLoader is instantiated.\n    Args:\n        spatial_range: list([lat_min,lat_max,lon_min,lon_max])\n        area_limit: int (All regions should be smaller than)\n\n\n    '''\n    partition_func_dict = {\n        'grid':grid_partition,\n        'hexagon':hexagon_partition,\n        'road_network':roadnetwork_partition\n    }\n    bind_func_dict = {\n        'location':location_bind\n    }\n    cluster_func_dict = {\n        'async_fluid':async_fluid,\n        'node_swapping':node_swapping\n    }\n    def __init__(self,spatial_range,area_limit) -> None:\n        self.lat_min = spatial_range[0]\n        self.lat_max = spatial_range[1]\n        self.lon_min = spatial_range[2]\n        self.lon_max = spatial_range[3]\n        self.area_limit = area_limit\n\n\n    def partition(self,method,**params) -> any:\n        if method not in self.partition_func_dict:\n            logging.error(f\"Unsupported method of partition: {method}. Skipping.\")\n        else:\n            self.regions = self.partition_func_dict[method](**params)\n\n    def bind(self,df,method,**params) -> any:\n        if method not in self.bind_func_dict:\n            logging.error(f\"Unsupported method of bind: {method}. Skipping.\")\n        else:\n            self.demand_matrix = self.bind_func_dict[method](**params)\n        pass\n\n    def aggregate(self,cluster_method,merge_way='sum',**params) -> any:\n        if cluster_method not in self.partition_func_dict:\n            logging.error(f\"Unsupported method of aggregation: {cluster_method}. Skipping.\")\n        else:\n            regions2clusters,_ = self.cluster_func_dict[cluster_method](self.regions,**params)\n        num_clusters = max(regions2clusters)\n        new_demand_matrix = np.zeros([self.demand_matrix.shape[0],num_clusters])\n        for i in range(num_clusters):\n            \n            if merge_way == 'sum':\n                new_demand_matrix[:,i] = np.sum(self.demand_matrix[:,np.nonzero(regions2clusters==i)[0]])\n            elif merge_way == 'average':\n                new_demand_matrix[:,i] = np.average(self.demand_matrix[:,np.nonzero(regions2clusters==i)[0]])\n            else:\n                raise KeyError('not implemented')\n        new_regions = None # aggregate regions in to new regions (should be a single geometry but not collections of geometry)\n        return new_regions,new_demand_matrix\n\n        \n\n"
  },
  {
    "path": "UCTB/preprocess/__init__.py",
    "content": "from .preprocessor import Normalizer, SplitData, MoveSample, ST_MoveSample,chooseNormalizer\r\nfrom .time_utils import is_valid_date, is_work_day_america, is_work_day_china\r\n"
  },
  {
    "path": "UCTB/preprocess/dataset_helper.py",
    "content": "from dateutil.parser import parse\nimport pickle\nfrom datetime import timedelta\nimport os\n\ndef print_dic_info(dic, dic_name, tag=''):\n    for k in dic:\n        print(tag, end='')\n        if type(dic[k])==type({}):\n            print(f'{dic_name}[{k}]:{type(dic[k])}'+'{')\n            print_dic_info(dic[k], f'{dic_name}[{k}]', tag=tag+'\\t')\n            print('}', end='')\n        elif 'numpy' in str(type(dic[k])):\n            print(f'{dic_name}[{k}]:{type(dic[k])}  (shape={dic[k].shape})', end='')\n        elif type(dic[k])== type([]):\n            lis = dic[k]\n            s = f'({len(lis)}, {len(lis[0])})' if len(lis)>0 and type(lis[0])==type([]) else f'{len(lis)}'\n            print(f'{dic_name}[{k}]:{type(dic[k])}  (len={s})', end='')\n        else:\n            print(f'{dic_name}[{k}]:{type(dic[k])}', end='')\n        print()\n\ndef get_timedelta(dic):\n    return timedelta(days=0, seconds=0, microseconds=0,milliseconds=0, minutes=dic['TimeFitness'], hours=0, weeks=0)\n\n\ndef build_uctb_dataset(traffic_node, time_fitness, node_station_info, time_range, dataset_name, city,\n    traffic_monthly_interaction=None, external_feature_weather=None, node_poi=None, \n    traffic_grid=None, grid_lat_lng=None, gird_poi=None, print_dataset=False, output_dir=None):\n    \"\"\"\n    build and return the uctb dataset in dic format\n    necessary:\n        time_fitness\n        time_range\n        Node\n            traffic_node\n            node_satation_info          \n        \n    optional: \n        Node\n            traffic_monthly_interaction\n            poi\n        Grid\n            traffic_grid\n            gird_lat_lng\n            poi\n        ExternalFeature\n            Weather\n    \"\"\"\n    dataset = {'TimeRange':time_range, 'TimeFitness':time_fitness, 'Node':{'TrafficNode':traffic_node, 'StationInfo':node_station_info},\n                    'Grid':{}, 'ExternalFeature':{}, 'LenTimeSlots':traffic_node.shape[0]}\n\n    # make sure no data missing in traffic node\n    beg_dt = parse(dataset['TimeRange'][0])\n    assert beg_dt+(dataset['Node']['TrafficNode'].shape[0])*get_timedelta(dataset) == parse(dataset['TimeRange'][1])\n\n    dataset['Node']['TrafficMonthlyInteraction'] = traffic_monthly_interaction\n    dataset['Grid']['TrafficGrid'] = traffic_grid\n    dataset['Grid']['GridLatLng'] = grid_lat_lng\n    dataset['ExternalFeature']['Weather'] = [] if external_feature_weather is None else external_feature_weather\n    \n    if node_poi is not None:\n        dataset['Node']['POI'] = node_poi\n        \n    if gird_poi is not None:\n        dataset['Grid']['POI'] = gird_poi\n    \n    if print_dataset:\n        print_dic_info(dataset, 'dataset')\n\n    if output_dir is None:\n        pkl_file_name = '{}_{}.pkl'.format(dataset_name, city)\n    else:\n        pkl_file_name = os.path.join(output_dir, '{}_{}.pkl'.format(dataset_name, city))\n\n    with open(pkl_file_name, 'wb') as f:\n        pickle.dump(dataset, f)\n\n\ndef convert_uctb_data():\n    # To be implemented\n    pass"
  },
  {
    "path": "UCTB/preprocess/preprocessor.py",
    "content": "import numpy as np\r\nfrom abc import ABC, abstractmethod\r\n\r\n\r\nclass Normalizer(ABC):\r\n    \"\"\"\r\n    Normalizer is the base abstract class for many normalizers such as MaxMinNormalizer and ZscoreNormalizer.You can also build your own normalizer by inheriting this class.\r\n\r\n    Args:\r\n        X(ndarray): Data which normalizer extracts characteristics from.\r\n    \"\"\"\r\n    @abstractmethod\r\n    def __init__(self, X):\r\n        pass\r\n    @abstractmethod\r\n    def transform(self, X_in):\r\n        pass\r\n    @abstractmethod\r\n    def inverse_transform(self, X_in):\r\n        pass\r\n\r\n\r\n\r\nclass MaxMinNormalizer(Normalizer):\r\n    '''\r\n    This class can help normalize and denormalize data using maximum and minimum of data by calling transform and inverse_transform method.\r\n\r\n    Args:\r\n        X(ndarray): Data which normalizer extracts characteristics from.\r\n        method(str): Parameter to choose in which way the input data will be processed.\r\n    '''\r\n    def __init__(self, X,method='all'):\r\n        self.method = method\r\n        self._min = np.min(X)\r\n        self._max = np.max(X)\r\n        self._min_by_column = np.min(X,axis=0)\r\n        self._max_by_column = np.max(X,axis=0)\r\n\r\n    def transform(self, X):\r\n        '''\r\n        Process input data to obtain normalized data.\r\n\r\n        Args:\r\n            X(ndarray): input data. \r\n        :return: normalized data.\r\n        :type: numpy.ndarray.\r\n        '''\r\n        if self.method=='all':\r\n            return (X - self._min) / (self._max - self._min)\r\n        elif self.method=='column':\r\n            return (X - self._min_by_column) / (self._max_by_column - self._min_by_column)\r\n\r\n    def inverse_transform(self, X):\r\n        '''\r\n        Restore normalized data.\r\n\r\n        Args:\r\n            X(ndarray): normalized data. \r\n        :return: denormalized data.\r\n        :type: numpy.ndarray.\r\n        '''\r\n        if self.method=='all':\r\n            return X * (self._max - self._min) + self._min\r\n        elif self.method=='column':\r\n            return X * (self._max_by_column - self._min_by_column) + self._min_by_column\r\n\r\n\r\nclass WhiteNormalizer(Normalizer):\r\n    '''\r\n    This class's normalization won't do anything.\r\n    '''\r\n    def __init__(self, X,method='all'):\r\n        pass\r\n\r\n    def transform(self, X):\r\n        '''\r\n        Process input data to obtain normalized data.\r\n\r\n        Args:\r\n            X(ndarray): input data. \r\n        :return: normalized data.\r\n        :type: numpy.ndarray.\r\n        '''\r\n        return X\r\n\r\n    def inverse_transform(self, X):\r\n        '''\r\n        Restore normalized data.\r\n\r\n        Args:\r\n            X(ndarray): normalized data. \r\n        :return: denormalized data.\r\n        :type: numpy.ndarray.\r\n        '''\r\n        return X\r\n\r\nclass ZscoreNormalizer(Normalizer):\r\n    '''\r\n    This class can help normalize and denormalize data using mean and standard deviation in data by calling transform and inverse_transform method.\r\n\r\n    Args:\r\n        X(ndarray): Data which normalizer extracts characteristics from.\r\n        method(str): Parameter to choose in which way the input data will be processed.\r\n    '''\r\n    def __init__(self, X,method='all'):\r\n        self.method = method\r\n        self._mean = np.mean(X)\r\n        self._std = np.std(X)\r\n        self._mean_by_column = np.mean(X,axis=0)\r\n        self._std_by_column = np.std(X,axis=0)\r\n\r\n    def transform(self, X):\r\n        '''\r\n        Process input data to obtain normalized data.\r\n\r\n        Args:\r\n            X(ndarray): input data. \r\n        :return: normalized data.\r\n        :type: numpy.ndarray.\r\n        '''\r\n        if self.method=='all':\r\n            return (X - self._mean) / self._std\r\n        elif self.method=='column':\r\n            return (X - self._mean_by_column) / self._std_by_column\r\n\r\n    def inverse_transform(self, X):\r\n        '''\r\n        Restore normalized data.\r\n\r\n        Args:\r\n            X(ndarray): normalized data. \r\n        :return: denormalized data.\r\n        :type: numpy.ndarray.\r\n        '''\r\n        if self.method=='all':\r\n            return X * self._std + self._mean\r\n        elif self.method=='column':\r\n            return X * self._std_by_column + self._mean_by_column\r\n\r\n\r\nclass MoveSample(object):\r\n    def __init__(self, feature_step, feature_stride, feature_length, target_length):\r\n        self.feature_step = feature_step\r\n        self.feature_stride = feature_stride\r\n        self.feature_length = feature_length\r\n        self.target_length = target_length\r\n\r\n    def general_move_sample(self, data):\r\n        feature = []\r\n        target = []\r\n        # sample_num = len(data) - window_size + 1\r\n        # window_size = feature_length + (feature_step-1)*feature_stride + target_length\r\n        for i in range(len(data) - self.feature_length -\r\n                       (self.feature_step-1)*self.feature_stride - self.target_length + 1):\r\n            feature.append([data[i + step*self.feature_stride: i + step*self.feature_stride + self.feature_length]\r\n                            for step in range(self.feature_step)])\r\n            target.append(data[i + (self.feature_step-1) * self.feature_stride + self.feature_length:\\\r\n                               i + (self.feature_step-1) * self.feature_stride + self.feature_length + self.target_length])\r\n\r\n        return np.array(feature), np.array(target)\r\n\r\nclass ST_MoveSample(object):\r\n    '''\r\n    This class can converts raw data into temporal features including closenss, period and trend features.\r\n\r\n    Args:\r\n        closeness_len(int):The length of closeness data history. The former consecutive ``closeness_len`` time slots\r\n            of data will be used as closeness history.\r\n        period_len(int):The length of period data history. The data of exact same time slots in former consecutive\r\n            ``period_len`` days will be used as period history.\r\n        trend_len(int):The length of trend data history. The data of exact same time slots in former consecutive\r\n            ``trend_len`` weeks (every seven days) will be used as trend history.\r\n        target_length(int):The numbers of steps that need prediction by one piece of history data. Have to be 1 now.\r\n            Default: 1 default:1.\r\n        daily_slots(int): The number of records of one day. Calculated by 24 * 60 /time_fitness. default:24.\r\n    '''\r\n    def __init__(self, closeness_len, period_len, trend_len, target_length=1, daily_slots=24):\r\n        self._c_t = closeness_len\r\n        self._p_t = period_len\r\n        self._t_t = trend_len\r\n        self._target_length = target_length\r\n        self._daily_slots = daily_slots\r\n\r\n        # 1 init Move_Sample object\r\n        self.move_sample_closeness = MoveSample(feature_step=self._c_t, feature_stride=1,\r\n                                                feature_length=1, target_length=self._target_length)\r\n\r\n        self.move_sample_period = MoveSample(feature_step=self._p_t + 1, feature_stride=int(self._daily_slots),\r\n                                             feature_length=1, target_length=0)\r\n\r\n        self.move_sample_trend = MoveSample(feature_step=self._t_t + 1, feature_stride=int(self._daily_slots) * 7,\r\n                                            feature_length=1, target_length=0)\r\n\r\n    def move_sample(self, data):\r\n        '''\r\n        Input data to generate closeness, period, trend features and target vector y.\r\n\r\n        Args:\r\n            data(ndarray):Orginal temporal data.\r\n        :return:closeness, period, trend and y matrices.\r\n        :type: numpy.ndarray.\r\n        '''\r\n        # 2 general move sample\r\n        closeness, y = self.move_sample_closeness.general_move_sample(data)\r\n        period, _ = self.move_sample_period.general_move_sample(data)\r\n        trend, _ = self.move_sample_trend.general_move_sample(data)\r\n\r\n        # 3 remove the front part\r\n        min_length = min(len(closeness), len(period), len(trend))\r\n        closeness = closeness[-min_length:]\r\n        y = y[-min_length:]\r\n        period = period[-min_length:]\r\n        trend = trend[-min_length:]\r\n\r\n        # 4 remove tail of period and trend\r\n        period = period[:, :-1]\r\n        trend = trend[:, :-1]\r\n\r\n        if self._c_t and self._c_t > 0:\r\n            closeness = np.transpose(closeness, [0] + list(range(3, len(closeness.shape))) + [1, 2])\r\n        else:\r\n            closeness = np.array([])\r\n\r\n        if self._p_t and self._p_t > 0:\r\n            period = np.transpose(period, [0] + list(range(3, len(period.shape))) + [1, 2])\r\n        else:\r\n            period = np.zeros(shape=[min_length,closeness.shape[1],0,1])\r\n\r\n        if self._t_t and self._t_t > 0:\r\n            trend = np.transpose(trend, [0] + list(range(3, len(trend.shape))) + [1, 2])\r\n        else:\r\n            trend = np.zeros(shape=[min_length,closeness.shape[1],0,1])\r\n\r\n        y = np.transpose(y, [0] + list(range(2, len(y.shape))) + [1])\r\n\r\n        return closeness, period, trend, y\r\n\r\n\r\nclass SplitData(object):\r\n    '''\r\n    This class can help split data by calling split_data and split_feed_dict method.\r\n    '''\r\n    @staticmethod\r\n    def split_data(data, ratio_list):\r\n        '''\r\n        Divide the data based on the given parameter ratio_list.\r\n        \r\n        Args:\r\n            data(ndarray):Data to be split.\r\n            ratio_list(list):Split ratio, the `data` will be split according to the ratio.\r\n        :return:The elements in the returned list are the divided data, and the \r\n            dimensions of the list are the same as ratio_list.\r\n        :type: list\r\n        '''\r\n        if np.sum(ratio_list) != 1:\r\n            ratio_list = np.array(ratio_list)\r\n            ratio_list = ratio_list / np.sum(ratio_list)\r\n        return [data[int(sum(ratio_list[0:e])*len(data)):\r\n                     int(sum(ratio_list[0:e+1])*len(data))] for e in range(len(ratio_list))]\r\n\r\n    @staticmethod\r\n    def split_feed_dict(feed_dict, sequence_length, ratio_list):\r\n        '''\r\n        Divide the `value` data in `feed_dict` based on the given parameter ratio_list.\r\n\r\n        Args:\r\n            feed_dict(dict):It is a dictionary composed of `key-value` pairs.\r\n            sequence_length(int):If the length of `value` in `feed_dict` is equal to sequence_length, \r\n                then this method divides the `value` according to the ratio without changing its `key`.\r\n            ratio_list(list):Split ratio, the data will be split according to the ratio.\r\n        :return: The elements in the returned list are divided dictionaries, and the dimensions of the list are the same as ratio_list.\r\n        :type: list\r\n        '''\r\n        if np.sum(ratio_list) != 1:\r\n            ratio_list = np.array(ratio_list)\r\n            ratio_list = ratio_list / np.sum(ratio_list)\r\n\r\n        return [{key: value[int(sum(ratio_list[0:e])*len(value)):int(sum(ratio_list[0:e+1])*len(value))]\r\n                 if len(value) == sequence_length else value for key, value in feed_dict.items()}\r\n                for e in range(len(ratio_list))]\r\n\r\ndef chooseNormalizer(in_arg,X_train):\r\n    '''\r\n    Choose a proper normalizer consistent with user's input.\r\n\r\n    Args:\r\n        in_arg(str|bool|object):Function is based on it to choose different normalizer.\r\n        X_train(numpy.ndarray):Function is based on it to initialize the normalizer.\r\n    :return: The normalizer consistent with definition.\r\n    :type: object.\r\n    '''\r\n    if type(in_arg) == str:\r\n        if '-' in in_arg:\r\n            method,way=in_arg.split('-')\r\n            if method=='Zscore' or method=='zscore' or method=='ZScore':\r\n                return ZscoreNormalizer(X_train,way)\r\n            elif method=='MaxMin' or method=='maxmin' or method=='Maxmin' or method=='MinMax' or method=='Minmax' or method=='minmax':\r\n                return MaxMinNormalizer(X_train,way)\r\n            else:\r\n                raise ValueError('We havn\\'t support thie method for normalization yet')\r\n        else:\r\n            raise ValueError('We don\\'t accept this format of str input for how to do normalization')\r\n    elif type(in_arg) == bool:\r\n        if in_arg:\r\n            return MaxMinNormalizer(X_train)\r\n        else:\r\n            return WhiteNormalizer(X_train)\r\n    elif type(in_arg) == object:\r\n        if hasattr(in_arg,'transform') and hasattr(in_arg,'inverss_transform'):\r\n            return in_arg(X_train)\r\n        else:\r\n            raise TypeError('Your custom normalizer is not in compliance')\r\n    else:\r\n        raise TypeError('We don\\'t accept {} of input for how to do normalization')\r\n\r\nif __name__ == '__main__':\r\n    a = np.arange(0,1000)\r\n    st_movesample = ST_MoveSample(6,7,4)\r\n    closeness,period,trend,y = st_movesample.move_sample(a)\r\n    print(y)\r\n\r\n"
  },
  {
    "path": "UCTB/preprocess/time_utils.py",
    "content": "from dateutil.parser import parse\r\nfrom chinese_calendar import is_workday\r\nfrom workalendar.usa import NewYork, DistrictOfColumbia, Illinois\r\n\r\namerica_public_holiday = ['01-01', '01-02', '01-16', '02-12', '02-13', '02-20', '05-29', '07-04', '09-04',\r\n                          '10-09', '11-10', '11-11', '11-23', '12-25']\r\n\r\n\r\ndef is_work_day_america(date, city):\r\n    \"\"\"\r\n    Args:\r\n        date(string or datetime): e.g. 2019-01-01\r\n\r\n    Return:\r\n        True if date is not holiday in America,\r\n        otherwise return False.\r\n    \"\"\"\r\n    if type(date) is str:\r\n        date = parse(date)\r\n\r\n    if city == \"Chicago\":\r\n        workday = Illinois()\r\n    elif city == \"NYC\":\r\n        workday = NewYork()\r\n    elif city == \"DC\":\r\n        workday = DistrictOfColumbia()\r\n    else:\r\n        raise ValueError(\"can't parse holiday in {}.\".format(city))\r\n    return workday.is_working_day(date)\r\n\r\n\r\ndef is_work_day_china(date, city):\r\n    \"\"\"\r\n    Args:\r\n        date(string or datetime): e.g. 2019-01-01\r\n\r\n    Return:\r\n        True if date is not holiday in China,\r\n        otherwise return False.\r\n    \"\"\"\r\n    if type(date) is str:\r\n        date = parse(date)\r\n    return is_workday(date)\r\n\r\n\r\ndef is_valid_date(date_str):\r\n    \"\"\"\r\n    Args:\r\n        date_str(string): e.g. 2019-01-01\r\n\r\n    Return:\r\n        True if date_str is valid date,\r\n        otherwise return False.\r\n    \"\"\"\r\n    try:\r\n        date = parse(date_str)\r\n    except:\r\n        return False\r\n\r\n    year = date.year\r\n    month = date.month\r\n    day = date.day\r\n\r\n    isRunNian = False\r\n    if year % 4 == 0 and year % 100 != 0 and year % 400 == 0:\r\n        isRunNian = True\r\n\r\n    if month < 1 or month > 12:\r\n        return False\r\n\r\n    pingnian_month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\r\n    runnian_month = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\r\n\r\n    if isRunNian:\r\n        if day < 1 or day > pingnian_month[month]:\r\n            return False\r\n    else:\r\n        if day < 1 or day > runnian_month[month]:\r\n            return False\r\n\r\n    return True\r\n"
  },
  {
    "path": "UCTB/train/EarlyStopping.py",
    "content": "from scipy import stats\r\n\r\n\r\nclass EarlyStopping(object):\r\n    \"\"\"Early stop if a span of newest records are not better than the current best record.\r\n\r\n    Args:\r\n        patience (int): The span of checked newest records.\r\n\r\n    Attributes:\r\n        __record_list (list): List of records.\r\n        __best (float): The current best record.\r\n        __patience (int): The span of checked newest records.\r\n        __p (int): The number of newest records that are worse than the current best record.\r\n\r\n    \"\"\"\r\n    def __init__(self, patience):\r\n        self.__record_list = []\r\n        self.__best = None\r\n        self.__patience = patience\r\n        self.__p = 0\r\n\r\n    def stop(self, new_value):\r\n        \"\"\"Append the new record to the record list\r\n        and check if the number of new records than are worse than the best records exceeds the limit.\r\n\r\n        Args:\r\n            new_value (float): The new record generated by the newest model.\r\n\r\n        Returns:\r\n            bool: ``True`` if the number of new records than are worse than the best records exceeds the limit and\r\n            triggers early stop, otherwise ``False``.\r\n        \"\"\"\r\n        self.__record_list.append(new_value)\r\n        if self.__best is None or new_value < self.__best:\r\n            self.__best = new_value\r\n            self.__p = 0\r\n            return False\r\n        else:\r\n            if self.__p < self.__patience:\r\n                self.__p += 1\r\n                return False\r\n            else:\r\n                return True\r\n\r\n\r\nclass EarlyStoppingTTest(object):\r\n    \"\"\"Early Stop by t-test.\r\n\r\n    T-test is a two-sided test for the null hypothesis that 2 independent samples\r\n    have identical average (expected) values. This method takes two intervals according to ``length``\r\n    in the record list and see if they have identical average values. If so, do early stop.\r\n\r\n    Args:\r\n        length (int): The length of checked interval.\r\n        p_value_threshold (float): The p-value threshold to decide whether to do early stop.\r\n\r\n    Attributes:\r\n        __record_list (list): List of records.\r\n        __best (float): The current best record.\r\n        __test_length (int): The length of checked interval.\r\n        __p_value_threshold (float): The p-value threshold to decide whether to do early stop.\r\n    \"\"\"\r\n    def __init__(self, length, p_value_threshold):\r\n        self.__record_list = []\r\n        self.__best = None\r\n        self.__test_length = length\r\n        self.__p_value_threshold = p_value_threshold\r\n\r\n    def stop(self, new_value):\r\n        \"\"\"\r\n        Take two intervals in the record list to do t-test.\r\n\r\n        Args:\r\n            new_value (float): The new record generated by the newest model.\r\n\r\n        Returns:\r\n            bool: ``True`` if p value of t-test is smaller than threshold and\r\n            triggers early stop, otherwise ``False``.\r\n        \"\"\"\r\n        self.__record_list.append(new_value)\r\n        if len(self.__record_list) >= (self.__test_length * 2):\r\n            lossTTest = stats.ttest_ind(self.__record_list[-self.__test_length:],\r\n                                        self.__record_list[-self.__test_length * 2:-self.__test_length], equal_var=False)\r\n            ttest = lossTTest[0]\r\n            pValue = lossTTest[1]\r\n            print('ttest:', ttest, 'pValue', pValue)\r\n            if pValue > self.__p_value_threshold or ttest > 0:\r\n                return True\r\n            else:\r\n                return False\r\n        else:\r\n            return False\r\n"
  },
  {
    "path": "UCTB/train/LossFunction.py",
    "content": "import numpy as np\nimport torch\nimport tensorflow as tf\nimport mxnet as mx\n\ndef masked_mse(preds, labels, null_val=np.nan):\n    if np.isnan(null_val):\n        mask = ~torch.isnan(labels)\n    else:\n        mask = (labels != null_val)\n    mask = mask.float()\n    # print(mask.sum())\n    # print(mask.shape[0]*mask.shape[1]*mask.shape[2])\n    mask /= torch.mean((mask))\n    mask = torch.where(torch.isnan(mask), torch.zeros_like(mask), mask)\n    loss = (preds - labels)**2\n    loss = loss * mask\n    loss = torch.where(torch.isnan(loss), torch.zeros_like(loss), loss)\n    return torch.mean(loss)\n\n\ndef masked_rmse(preds, labels, null_val=np.nan):\n    return torch.sqrt(masked_mse(preds=preds, labels=labels,\n                                 null_val=null_val))\n\n\ndef masked_mae(preds, labels, null_val=np.nan):\n    if np.isnan(null_val):\n        mask = ~torch.isnan(labels)\n    else:\n        mask = (labels != null_val)\n    mask = mask.float()\n    mask /= torch.mean((mask))\n    mask = torch.where(torch.isnan(mask), torch.zeros_like(mask), mask)\n    loss = torch.abs(preds - labels)\n    loss = loss * mask\n    loss = torch.where(torch.isnan(loss), torch.zeros_like(loss), loss)\n    return torch.mean(loss)\n\n\ndef masked_mape(preds, labels, null_val=np.nan):\n    if np.isnan(null_val):\n        mask = ~torch.isnan(labels)\n    else:\n        mask = (labels != null_val)\n    mask = mask.float()\n    mask /= torch.mean((mask))\n    mask = torch.where(torch.isnan(mask), torch.zeros_like(mask), mask)\n    loss = torch.abs(preds-labels)/labels\n    loss = loss * mask\n    loss = torch.where(torch.isnan(loss), torch.zeros_like(loss), loss)\n    return torch.mean(loss)\n\n\ndef mae_loss(pred, label):\n    mask = tf.not_equal(label, 0)\n    mask = tf.cast(mask, tf.float32)\n    mask /= tf.reduce_mean(mask)\n    # mask = tf.compat.v2.where(\n    #     condition = tf.math.is_nan(mask), x = 0., y = mask)\n    mask = tf.compat.v1.where(\n        condition=tf.math.is_nan(mask), x=tf.zeros_like(mask), y=mask)\n    loss = tf.abs(tf.subtract(pred, label))\n    loss *= mask\n    # loss = tf.compat.v2.where(\n    #     condition = tf.math.is_nan(loss), x = 0., y = loss)\n    loss = tf.compat.v1.where(\n        condition=tf.math.is_nan(loss), x=tf.zeros_like(mask), y=loss)\n    loss = tf.reduce_mean(loss)\n    return loss\n\ndef mask_np(array, null_val):\n    '''\n    function for STSGCN\n    '''\n    if np.isnan(null_val):\n        return (~np.isnan(null_val)).astype('float32')\n    else:\n        return np.not_equal(array, null_val).astype('float32')\n\n\ndef masked_mse_np(y_true, y_pred, null_val=np.nan):\n    '''\n    function for STSGCN\n    '''\n    mask = mask_np(y_true, null_val)\n    mask /= mask.mean()\n    mse = (y_true - y_pred) ** 2\n    return np.mean(np.nan_to_num(mask * mse))\n\n\ndef masked_mae_np(y_true, y_pred, null_val=np.nan):\n    '''\n    function for STSGCN\n    '''\n    mask = mask_np(y_true, null_val)\n    mask /= mask.mean()\n    mae = np.abs(y_true - y_pred)\n    return np.mean(np.nan_to_num(mask * mae))\n\n\ndef masked_mape_np(y_true, y_pred, null_val=np.nan):\n    '''\n    function for STSGCN\n    '''\n    with np.errstate(divide='ignore', invalid='ignore'):\n        mask = mask_np(y_true, null_val)\n        mask /= mask.mean()\n        mape = np.abs((y_pred - y_true) / y_true)\n        mape = np.nan_to_num(mask * mape)\n        return np.mean(mape) * 100\n\n\ndef masked_mae_loss(mask_value):\n    '''\n    function for AGCRN\n    '''\n    def loss(preds, labels):\n        mae = MAE_torch(pred=preds, true=labels, mask_value=mask_value)\n        return mae\n    return loss\n\ndef MAE_torch(pred, true, mask_value=None):\n    if mask_value != None:\n        mask = torch.gt(true, mask_value)\n        pred = torch.masked_select(pred, mask)\n        true = torch.masked_select(true, mask)\n    return torch.mean(torch.abs(true-pred))\n\n\n\ndef huber_loss(data, label, rho=1):\n    '''\n    Parameters\n    ----------\n    data: mx.sym.var, shape is (B, T', N)\n\n    label: mx.sym.var, shape is (B, T', N)\n\n    rho: float\n\n    Returns\n    ----------\n    loss: mx.sym\n    '''\n\n    loss = mx.sym.abs(data - label)\n    loss = mx.sym.where(loss > rho, loss - 0.5 * rho,\n                        (0.5 / rho) * mx.sym.square(loss))\n    loss = mx.sym.MakeLoss(loss)\n    return loss\n"
  },
  {
    "path": "UCTB/train/MiniBatchTrain.py",
    "content": "import numpy as np\r\n\r\n\r\nclass MiniBatchTrain():\r\n    '''\r\n    Get small batches of data for training at once.\r\n\r\n    Args:\r\n        X(ndarray):Input features. The first dimension of X should be sample size.\r\n        Y(ndarray):Target values. The first dimension of Y should be sample size.\r\n        batch_size(int): The number of data for one training session.\r\n    '''\r\n    def __init__(self, X, Y, batch_size):\r\n        # The first dimension of X should be sample size\r\n        # The first dimension of Y should be sample size\r\n\r\n        self.__X, self.__Y = self.shuffle(X, Y)\r\n\r\n        self.__sample_size = len(X)\r\n\r\n        self.__batch_counter = 0\r\n        self.__batch_size = batch_size\r\n\r\n        self.num_batch = int(self.__sample_size / self.__batch_size) \\\r\n        if self.__sample_size % self.__batch_size == 0 else int(self.__sample_size / self.__batch_size) + 1\r\n\r\n    @staticmethod\r\n    def shuffle(X, Y):\r\n        '''\r\n        Input (X, Y) pairs, shuffle and return it.\r\n        '''\r\n        xy = list(zip(X, Y))\r\n        np.random.shuffle(xy)\r\n        return np.array([e[0] for e in xy], dtype=np.float32), np.array([e[1] for e in xy], dtype=np.float32)\r\n\r\n    def get_batch(self):\r\n        '''\r\n        Returns a batch of X, Y pairs each time. There are internal variables \r\n        to record the number of batches currently generated. When the last data \r\n        is not enough to generate a batch, a batch of data from the tail is returned.\r\n        '''\r\n        if self.__batch_counter + self.__batch_size <= self.__sample_size:\r\n            batch_x = self.__X[self.__batch_counter: self.__batch_counter + self.__batch_size]\r\n            batch_y = self.__Y[self.__batch_counter: self.__batch_counter + self.__batch_size]\r\n            self.__batch_counter = self.__batch_counter + self.__batch_size\r\n        else:\r\n            batch_x = self.__X[-self.__batch_size: ]\r\n            batch_y = self.__Y[-self.__batch_size: ]\r\n            self.__batch_counter = 0\r\n\r\n        return batch_x, batch_y\r\n\r\n    def restart(self):\r\n        '''\r\n        Set the variable that records the number of batches currently generated to 0, so that \r\n        we can call the `get_batch` method to generate training data in batches from scratch.\r\n        '''\r\n        self.__batch_counter = 0\r\n\r\n\r\nclass MiniBatchTrainMultiData(object):\r\n    '''\r\n    Get small batches of data for training at once.\r\n\r\n    Args:\r\n        data(ndarray): Input data. Its first dimension should be sample size.\r\n        batch_size(int): The number of data for one training session.\r\n        shuffle(bool): If set `True`, the input data will be shuffled. default:True.\r\n    '''\r\n    def __init__(self, data, batch_size, shuffle=True):\r\n        if shuffle:\r\n            self.__data = self.shuffle(data)\r\n        else:\r\n            self.__data = data\r\n\r\n        self.__sample_size = len(self.__data[0])\r\n\r\n        self.__batch_counter = 0\r\n        self.__batch_size = batch_size\r\n\r\n        self.num_batch = int(self.__sample_size / self.__batch_size) \\\r\n        if self.__sample_size % self.__batch_size == 0 else int(self.__sample_size / self.__batch_size) + 1\r\n\r\n    @staticmethod\r\n    def shuffle(data):\r\n        middle = list(zip(*data))\r\n        np.random.shuffle(middle)\r\n        return list(zip(*middle))\r\n\r\n    def get_batch(self):\r\n        '''\r\n        Returns a batch of data each time. There are internal variables \r\n        to record the number of batches currently generated. When the last data \r\n        is not enough to generate a batch, a batch of data from the tail is returned.\r\n        '''\r\n        if self.__batch_counter + self.__batch_size <= self.__sample_size:\r\n            index = [self.__batch_counter, self.__batch_counter + self.__batch_size]\r\n            self.__batch_counter = self.__batch_counter + self.__batch_size\r\n        else:\r\n            index = [self.__sample_size-self.__batch_size, self.__sample_size]\r\n            self.__batch_counter = 0\r\n\r\n        return [np.array(e[index[0]: index[1]]) for e in self.__data]\r\n\r\n    def restart(self):\r\n        '''\r\n        Set the variable that records the number of batches currently generated to 0, so that \r\n        we can call the `get_batch` method to generate training data in batches from scratch.\r\n        '''\r\n        self.__batch_counter = 0\r\n\r\n\r\nclass MiniBatchFeedDict(object):\r\n    '''\r\n    Get small batches of data from dict for training at once.\r\n\r\n    Args:\r\n        feed_dict(dict): Data dictionary consisting of key-value pairs.\r\n        sequence_length(int): Only divide value in `feed_dict` whose length is equal \r\n            to `sequence_length` into several batches.\r\n        batch_size(int): The number of data for one training session.\r\n        shuffle(bool): If set `True`, the input dict will be shuffled. default:True.\r\n    '''\r\n    def __init__(self, feed_dict, sequence_length, batch_size, shuffle=True):\r\n\r\n        self._sequence_length = sequence_length\r\n        self._batch_size = batch_size\r\n\r\n        self._dynamic_data_names = []\r\n        self._dynamic_data_values = []\r\n\r\n        self._batch_dict = {}\r\n\r\n        for key, value in feed_dict.items():\r\n            if len(value) == sequence_length:\r\n                self._dynamic_data_names.append(key)\r\n                self._dynamic_data_values.append(value)\r\n            else:\r\n                self._batch_dict[key] = value\r\n\r\n        if shuffle:\r\n            self._dynamic_data_values = MiniBatchFeedDict.shuffle(self._dynamic_data_values)\r\n\r\n        self._batch_counter = 0\r\n\r\n        self.num_batch = int(self._sequence_length / self._batch_size) \\\r\n            if self._sequence_length % self._batch_size == 0 else int(self._sequence_length / self._batch_size) + 1\r\n\r\n    def get_batch(self):\r\n        '''\r\n        For the `value` in `feed_dict` whose length is equal to sequence_length, divide the `value` \r\n        into several batches, and return one batch in order each time. For those whose length is not \r\n        equal to sequence_length, do not change `value`and return it directly. There are internal variables \r\n        to record the number of batches currently generated. When the last data is not enough to \r\n        generate a batch, a batch of data from the tail is returned.\r\n        '''\r\n        if self._batch_counter + self._batch_size <= self._sequence_length:\r\n            index = [self._batch_counter, self._batch_counter + self._batch_size]\r\n            self._batch_counter += self._batch_size\r\n        else:\r\n            index = [self._sequence_length-self._batch_size, self._sequence_length]\r\n            self._batch_counter = 0\r\n\r\n        for i in range(len(self._dynamic_data_names)):\r\n            key = self._dynamic_data_names[i]\r\n            self._batch_dict[key] = np.array(self._dynamic_data_values[i][index[0]:index[1]])\r\n\r\n        return self._batch_dict\r\n\r\n    @staticmethod\r\n    def shuffle(data):\r\n        middle = list(zip(*data))\r\n        np.random.shuffle(middle)\r\n        return list(zip(*middle))\r\n\r\n    def restart(self):\r\n        '''\r\n        Set the variable that records the number of batches currently generated to 0, so that \r\n        we can call the `get_batch` method to generate training data in batches from scratch.\r\n        '''\r\n        self._batch_counter = 0\r\n"
  },
  {
    "path": "UCTB/train/__init__.py",
    "content": "from .EarlyStopping import EarlyStopping\nfrom .EarlyStopping import EarlyStoppingTTest\n\nfrom .MiniBatchTrain import MiniBatchTrain, MiniBatchTrainMultiData, MiniBatchFeedDict\n\nfrom .LossFunction import *"
  },
  {
    "path": "UCTB/utils/__init__.py",
    "content": "from .multi_threads import multiple_process\nfrom .make_predict_dataset import save_predict_in_dataset"
  },
  {
    "path": "UCTB/utils/make_predict_dataset.py",
    "content": "import copy\nimport pickle as pkl\nimport os\nimport numpy as np\nfrom dateutil.parser import parse\nfrom datetime import timedelta\nimport pandas as pd\n\ndef save_predict_in_dataset(data_loader, predict_val, method):\n    data_dir = os.path.join(os.path.dirname(\n        os.path.dirname(os.path.abspath(__file__))), 'data')\n\n    original_file = os.path.join(data_dir, \"{}_{}.pkl\".format(\n        data_loader.dataset.dataset, data_loader.dataset.city))\n    file_name = os.path.join(data_dir, \"{}_{}_pred.pkl\".format(\n        data_loader.dataset.dataset, data_loader.dataset.city))\n\n    if os.path.exists(file_name):\n        with open(file_name, \"rb\") as fp:\n            pred_data = pkl.load(fp)\n    else:\n        with open(original_file, \"rb\") as fp:\n            pred_data = pkl.load(fp)\n            pred_data['Pred'] = {}\n\n    loader_id = data_loader.loader_id\n    if loader_id not in pred_data[\"Pred\"].keys():\n        pred_data['Pred'][loader_id] = {}\n\n    pred_data['Pred'][loader_id][\"GroundTruth\"] = np.squeeze(\n        data_loader.test_y)\n\n    if loader_id.endswith(\"N\"):\n        # use NodeTrafficLoader\n        pred_data['Pred'][loader_id][method] = {}\n        pred_data['Pred'][loader_id][method][\"traffic_data_index\"] = data_loader.traffic_data_index\n        pred_data['Pred'][loader_id][method][\"TrafficNode\"] = np.squeeze(predict_val)\n\n    if loader_id.endswith(\"G\"):\n        # use GridTrafficLoader\n        pred_data['Pred'][loader_id][method] = {}\n        pred_data['Pred'][loader_id][method][\"TrafficGrid\"] = np.squeeze(predict_val)\n\n    with open(file_name, \"wb\") as fp:\n        pkl.dump(pred_data, fp)\n    \ndef save_predict_and_graph_in_tsv_and_array(data_loader, prediction,args_list, is_graph=False, output_dir='output',graph=None):\n\n    #TODO: add an argument used to choose whether train set or test set is saved or both.\n    #TODO: text form to save information of time_fitness and time_range\n\n    # get access to original dataset\n    \n    dataset = data_loader.dataset\n\n    end_date = dataset.time_range[1]\n    loader_id = data_loader.loader_id\n    \n    # parse parameters setting through loader_id\n    \n    data_range, train_data_length, test_ratio, closeness_len, period_len, trend_len, time_fitness,_= loader_id.split('_')\n    \n    # get reasonable range of data we use\n    \n    if type(data_range) is str and data_range.lower().startswith(\"0.\"):\n        data_range = float(data_range)\n    if type(data_range) is str and data_range.lower() == 'all':\n        data_range = [0, len(data_loader.dataset.node_traffic)]\n    elif type(data_range) is float:\n        data_range = [0, int(data_range * len(data_loader.dataset.node_traffic))]\n    else:\n        data_range = [int(data_range[0] * data_loader.daily_slots), int(data_range[1] * data_loader.daily_slots)]\n    \n    # get total number of time slots we use\n    \n    number_of_ts = data_range[1] - data_range[0]\n    test_start_index = int(data_loader.train_test_ratio[0] * number_of_ts)\n    assert int(number_of_ts-test_start_index) == data_loader.test_y.shape[0]\n    td = timedelta(minutes=int(time_fitness))\n\n    # obtain begining and ending date of test set\n\n    test_set_start_date = (parse(end_date) - td*(len(dataset.node_traffic)-test_start_index)).strftime('%Y-%m-%d %H:%M:%S')\n    test_set_end_date = (parse(end_date) - td*(len(dataset.node_traffic)-number_of_ts)).strftime('%Y-%m-%d %H:%M:%S')\n    traffic_data_index = list(data_loader.traffic_data_index)\n    station_info = []\n    for ind in traffic_data_index:\n        station_info.append(dataset.node_station_info[ind])\n\n\n    if type(args_list) == list:\n        method = ''.join(args_list)\n    else:\n        method = args_list\n\n    # get dataset name\n    file_name_without_extension = '{}_{}_{}'.format(dataset.dataset , dataset.city , method)\n\n    \n    if not os.path.exists(output_dir):\n        os.makedirs(output_dir)\n    gt_list = data_loader.test_y.reshape([-1,207])\n    pd_list = prediction\n    gt_df = pd.DataFrame(gt_list)\n    pd_df = pd.DataFrame(pd_list)\n    gt_df = gt_df.transpose()\n    pd_df = pd_df.transpose()\n\n    station_info_df = pd.DataFrame(station_info)\n    station_info_df = station_info_df.drop(station_info_df.columns[[0, 1, 4]], axis=1)\n    gt_path = os.path.join(output_dir,file_name_without_extension + '_gt.tsv')\n    pd_path = os.path.join(output_dir,file_name_without_extension + '_pd.tsv')\n    station_info_path = os.path.join(output_dir,file_name_without_extension + '_station_info.tsv')\n    \n    # generate npy files\n    \n    np.save(os.path.join(output_dir,file_name_without_extension + '_gt.npy'),gt_list)\n    np.save(os.path.join(output_dir,file_name_without_extension + '_pd.npy'),pd_list)\n    \n    # generate graph\n    \n    if is_graph:\n        np.save(os.path.join(output_dir,file_name_without_extension + '_graph.npy'),graph)\n    \n    # generate tsv files\n\n    try:\n        gt_df.to_csv(gt_path, sep='\\t', index=False, header=False)\n        pd_df.to_csv(pd_path, sep='\\t', index=False, header=False)\n        station_info_df.to_csv(station_info_path, sep='\\t', index=False,\n                               header=False)\n        print(\"TSV files generated successfully!\")\n    except Exception as e:\n        print(\"Error while generating TSV files:\", e)\n\n    print('start time:{};end time:{}'.format(test_set_start_date,test_set_end_date))\n    print('time fitness:{}'.format(int(time_fitness)))\n    return [test_set_start_date,test_set_end_date], int(time_fitness)\n\ndef save_predict_and_graph_in_tsv_and_array(data_loader, prediction,args_list, output_dir='output',graph=None):\n\n    #TODO: add an argument used to choose whether train set or test set is saved or both.\n    #TODO: text form to save information of time_fitness and time_range\n\n    # get access to original dataset\n\n    dataset = data_loader.dataset\n\n    end_date = dataset.time_range[1]\n    loader_id = data_loader.loader_id\n    # parse parameters setting through loader_id\n\n    data_range, train_data_length, test_ratio, closeness_len, period_len, trend_len, time_fitness,_= loader_id.split('_')\n    \n    # get reasonable range of data we use\n\n    if type(data_range) is str and data_range.lower().startswith(\"0.\"):\n        data_range = float(data_range)\n    if type(data_range) is str and data_range.lower() == 'all':\n        data_range = [0, len(data_loader.dataset.node_traffic)]\n    elif type(data_range) is float:\n        data_range = [0, int(data_range * len(data_loader.dataset.node_traffic))]\n    else:\n        data_range = [int(data_range[0] * data_loader.daily_slots), int(data_range[1] * data_loader.daily_slots)]\n    \n    # get total number of time slots we use\n\n    number_of_ts = data_range[1] - data_range[0]\n    \n    test_start_index = data_range[0]+int(data_loader.train_test_ratio[0] * number_of_ts)\n    assert int(data_range[1]-test_start_index) == data_loader.test_y.shape[0]\n\n    # obtain begining and ending date of test set\n\n    td = timedelta(minutes=int(time_fitness))\n    test_set_start_date = (parse(end_date) - td*(len(dataset.node_traffic)-test_start_index+1)).strftime('%Y-%m-%d %H:%M:%S')\n    test_set_end_date = (parse(end_date) - td*(len(dataset.node_traffic)-data_range[1]+1)).strftime('%Y-%m-%d %H:%M:%S')\n\n    traffic_data_index = list(data_loader.traffic_data_index)\n    station_info = []\n    for ind in traffic_data_index:\n        station_info.append(dataset.node_station_info[ind])\n\n\n    if type(args_list) == list:\n        method = ''.join(args_list)\n    else:\n        method = args_list\n\n    # set output tsv name\n    file_name_without_extension = '{}_{}_{}'.format(dataset.dataset , dataset.city , method)\n\n    # generate pred and gt station_info in tsv files\n\n    if not os.path.exists(output_dir):\n        os.makedirs(output_dir)\n\n    gt_list = data_loader.test_y.reshape([-1,207])\n    pd_list = prediction\n    gt_df = pd.DataFrame(gt_list)\n    pd_df = pd.DataFrame(pd_list)\n    gt_df = gt_df.transpose()\n    pd_df = pd_df.transpose()\n    station_info_df = pd.DataFrame(station_info)\n    station_info_df = station_info_df.drop(station_info_df.columns[[0, 1, 4]], axis=1)\n    gt_path = os.path.join(output_dir,file_name_without_extension + '_gt.tsv')\n    pd_path = os.path.join(output_dir,file_name_without_extension + '_pd.tsv')\n    station_info_path = os.path.join(output_dir,file_name_without_extension + '_station_info.tsv')\n\n    # generate pred and gt in npy files and station_info in pkl file\n\n    np.save(os.path.join(output_dir,file_name_without_extension + '_gt.npy'),gt_list)\n    np.save(os.path.join(output_dir,file_name_without_extension + '_pd.npy'),pd_list)\n    with open(os.path.join(output_dir,file_name_without_extension + '_station_info.pkl'),'wb') as fp:\n        pkl.dump(station_info,fp)\n        \n    # generate graph files\n\n    if graph is None:\n        np.save(os.path.join(output_dir,file_name_without_extension + '_graph.npy'),graph)\n\n    # save tsv files\n\n    try:\n        gt_df.to_csv(gt_path, sep='\\t', index=False, header=False)\n        pd_df.to_csv(pd_path, sep='\\t', index=False, header=False)\n        station_info_df.to_csv(station_info_path, sep='\\t', index=False,\n                               header=False)\n        print(\"TSV files generated successfully!\")\n    except Exception as e:\n        print(\"Error while generating TSV files:\", e)\n\n    print('start time:{};end time:{}'.format(test_set_start_date,test_set_end_date))\n    print('time fitness:{}'.format(int(time_fitness)))\n    return [test_set_start_date,test_set_end_date], int(time_fitness)"
  },
  {
    "path": "UCTB/utils/multi_threads.py",
    "content": "import os\n\nfrom multiprocessing import Pool, Manager\nfrom functools import reduce\n\n\n# (my_rank, n_jobs, dataList, resultHandleFunction, parameterList)\ndef multiple_process(distribute_list, partition_func, task_func, n_jobs, reduce_func, parameters):\n\n    \"\"\"\n    Args:\n\n        distribute_list(list): The \"data\" list to be partitioned, such as a list of files which will be\n            distributed among different tasks and each task process a part of the files.\n        partition_func(function): Partition function will be used to cut the distribute_list, it should accept\n            three inputs: distribute_list, i, n_job, where i is the index of jobs (i.e. integer from 0 to n_jobs-1),\n            n_jos is the number of threads; partition function should return a data_list for the job_i\n        task_func(function): Task function, where the inputs are share_queue, locker, data, parameters, no return.\n            pls refer to the DiDi-Data processing codes for more information.\n        n_jobs(int): Number of threads\n        reduce_func(function): Reduce function which combine the outputs from all the threads into one final output.\n        parameters(list): parameters send to the task function\n\n    \"\"\"\n\n    if callable(partition_func) and callable(task_func) and callable(reduce_func):\n        print('Parent process %s.' % os.getpid())\n\n        manager = Manager()\n        share_queue = manager.Queue()\n        locker = manager.Lock()\n\n        p = Pool()\n        for i in range(n_jobs):\n            p.apply_async(task_func, args=(share_queue, locker, partition_func(distribute_list, i, n_jobs),\n                                           [i] + parameters,))\n        print('Waiting for all sub_processes done...')\n        p.close()\n        p.join()\n        print('All sub_processes done.')\n\n        result_list = []\n        while not share_queue.empty():\n            result_list.append(share_queue.get_nowait())\n\n        return reduce(reduce_func, result_list)\n    else:\n        print('Parameter error')\n\n\n\"\"\"\n# Example\ndef task(share_queue, locker, data, parameters):\n\n    print('Child process %s with pid %s' % (parameters[0], os.getpid()))\n\n    result = sum(data)\n\n    locker.acquire()\n    share_queue.put(result)\n    locker.release()\n\n\nif __name__ == \"__main__\":\n\n    data = [e for e in range(1000000)]\n\n    n_job = 4\n\n    sum_result = \\\n        multiple_process(distribute_list=data,\n                         partition_func=lambda data, i, n_job: [data[e] for e in range(len(data)) if e % n_job == i],\n                         task_func=task, n_jobs=n_job, reduce_func=lambda x, y: x + y, parameters=[])\n\n    print('Result', sum_result)\n\"\"\""
  },
  {
    "path": "UCTB/utils/utils_AGCRN.py",
    "content": "import torch\nimport torch.nn as nn\nimport numpy as np\nimport os\nimport logging\nimport math\nimport time\nimport copy\nfrom UCTB.preprocess import SplitData\nfrom UCTB.train.LossFunction import masked_mae_loss\n\n\nclass Trainer(object):\n    def __init__(self, model, train_loader, val_loader, test_loader,\n                 args):\n        super(Trainer, self).__init__()\n        self.model = model\n        self.optimizer = torch.optim.Adam(params=model.parameters(), lr=args.lr_init, eps=1.0e-8,\n                                          weight_decay=0, amsgrad=False)\n        self.train_loader = train_loader\n        self.val_loader = val_loader\n        self.test_loader = test_loader\n        self.args = args\n        self.train_per_epoch = len(train_loader)\n        self.lr_scheduler = None\n        for p in self.model.parameters():\n            if p.dim() > 1:\n                nn.init.xavier_uniform_(p)\n            else:\n                nn.init.uniform_(p)\n        if args.loss_func == 'mask_mae':\n            self.loss = masked_mae_loss(mask_value=0.0)\n        elif args.loss_func == 'mae':\n            self.loss = torch.nn.L1Loss().to(args.device)\n        elif args.loss_func == 'mse':\n            self.loss = torch.nn.MSELoss().to(args.device)\n        else:\n            raise ValueError\n        if args.lr_decay:\n            print('Applying learning rate decay.')\n            lr_decay_steps = [int(i)\n                              for i in list(args.lr_decay_step.split(','))]\n            self.lr_scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer=self.optimizer,\n                                                                     milestones=lr_decay_steps,\n                                                                     gamma=args.lr_decay_rate)\n        if val_loader != None:\n            self.val_per_epoch = len(val_loader)\n        self.best_path = os.path.join(self.args.log_dir, 'best_model.pth')\n        self.loss_figure_path = os.path.join(self.args.log_dir, 'loss.png')\n        # log\n        if os.path.isdir(args.log_dir) == False and not args.debug:\n            os.makedirs(args.log_dir, exist_ok=True)\n        self.logger = get_logger(\n            args.log_dir, name=args.model, debug=args.debug)\n        self.logger.info('Experiment log path in: {}'.format(args.log_dir))\n        # if not args.debug:\n        # self.logger.info(\"Argument: %r\", args)\n        # for arg, value in sorted(vars(args).items()):\n        #     self.logger.info(\"Argument %s: %r\", arg, value)\n\n    def val_epoch(self, epoch, val_dataloader):\n        self.model.eval()\n        total_val_loss = 0\n\n        with torch.no_grad():\n            for batch_idx, (data, target) in enumerate(val_dataloader):\n                label = target[..., :self.args.output_dim]\n                output = self.model(data, target, teacher_forcing_ratio=0.)\n                #loss = self.loss(output.cuda(), label)\n                loss = self.loss(output, label)\n                # a whole batch of Metr_LA is filtered\n                if not torch.isnan(loss):\n                    total_val_loss += loss.item()\n        val_loss = total_val_loss / len(val_dataloader)\n        self.logger.info(\n            '**********Val Epoch {}: average Loss: {:.6f}'.format(epoch, val_loss))\n        return val_loss\n\n    def train_epoch(self, epoch):\n        self.model.train()\n        total_loss = 0\n        for batch_idx, (data, target) in enumerate(self.train_loader):\n            label = target[..., :self.args.output_dim]  # (..., 1)\n            self.optimizer.zero_grad()\n\n            # teacher_forcing for RNN encoder-decoder model\n            # if teacher_forcing_ratio = 1: use label as input in the decoder for all steps\n            if self.args.teacher_forcing:\n                global_step = (epoch - 1) * self.train_per_epoch + batch_idx\n                teacher_forcing_ratio = self._compute_sampling_threshold(\n                    global_step, self.args.tf_decay_steps)\n            else:\n                teacher_forcing_ratio = 1.\n            # data and target shape: B, T, N, F; output shape: B, T, N, F\n            output = self.model(\n                data, target, teacher_forcing_ratio=teacher_forcing_ratio)\n            #loss = self.loss(output.cuda(), label)\n            loss = self.loss(output, label)\n            loss.backward()\n\n            # add max grad clipping\n            if self.args.grad_norm:\n                torch.nn.utils.clip_grad_norm_(\n                    self.model.parameters(), self.args.max_grad_norm)\n            self.optimizer.step()\n            total_loss += loss.item()\n\n            # log information\n            if batch_idx % self.args.log_step == 0:\n                self.logger.info('Train Epoch {}: {}/{} Loss: {:.6f}'.format(\n                    epoch, batch_idx, self.train_per_epoch, loss.item()))\n        train_epoch_loss = total_loss / self.train_per_epoch\n        self.logger.info(\n            '**********Train Epoch {}: averaged Loss: {:.6f}, tf_ratio: {:.6f}'.format(epoch, train_epoch_loss,\n                                                                                       teacher_forcing_ratio))\n\n        # learning rate decay\n        if self.args.lr_decay:\n            self.lr_scheduler.step()\n        return train_epoch_loss\n\n    def train(self):\n        best_model = None\n        best_loss = float('inf')\n        not_improved_count = 0\n        train_loss_list = []\n        val_loss_list = []\n        start_time = time.time()\n        for epoch in range(1, self.args.epochs + 1):\n            # epoch_time = time.time()\n            train_epoch_loss = self.train_epoch(epoch)\n            # print(time.time()-epoch_time)\n            # exit()\n            if self.val_loader == None:\n                val_dataloader = self.test_loader\n            else:\n                val_dataloader = self.val_loader\n            val_epoch_loss = self.val_epoch(epoch, val_dataloader)\n\n            # print('LR:', self.optimizer.param_groups[0]['lr'])\n            train_loss_list.append(train_epoch_loss)\n            val_loss_list.append(val_epoch_loss)\n            if train_epoch_loss > 1e6:\n                self.logger.warning('Gradient explosion detected. Ending...')\n                break\n            # if self.val_loader == None:\n            # val_epoch_loss = train_epoch_loss\n            if val_epoch_loss < best_loss:\n                best_loss = val_epoch_loss\n                not_improved_count = 0\n                best_state = True\n            else:\n                not_improved_count += 1\n                best_state = False\n            # early stop\n            if self.args.early_stop:\n                if not_improved_count == self.args.early_stop_patience:\n                    self.logger.info(\"Validation performance didn\\'t improve for {} epochs. \"\n                                     \"Training stops.\".format(self.args.early_stop_patience))\n                    break\n            # save the best state\n            if best_state == True:\n                self.logger.info(\n                    '*********************************Current best model saved!')\n                best_model = copy.deepcopy(self.model.state_dict())\n\n        training_time = time.time() - start_time\n        self.logger.info(\"Total training time: {:.4f}min, best loss: {:.6f}\".format(\n            (training_time / 60), best_loss))\n\n        # save the best model to file\n        if not self.args.debug:\n            torch.save(best_model, self.best_path)\n            self.logger.info(\"Saving current best model to \" + self.best_path)\n\n        # test\n        self.model.load_state_dict(best_model)\n        # self.val_epoch(self.args.epochs, self.test_loader)\n        #self.test(self.model, self.args, self.test_loader, self.scaler, self.logger)\n\n    def save_checkpoint(self):\n        state = {\n            'state_dict': self.model.state_dict(),\n            'optimizer': self.optimizer.state_dict(),\n            'config': self.args\n        }\n        torch.save(state, self.best_path)\n        self.logger.info(\"Saving current best model to \" + self.best_path)\n\n    @staticmethod\n    def test(model, args, data_loader,  logger, path=None):\n        if path != None:\n            check_point = torch.load(path)\n            state_dict = check_point['state_dict']\n            args = check_point['config']\n            model.load_state_dict(state_dict)\n            model.to(args.device)\n        model.eval()\n        y_pred = []\n        y_true = []\n        with torch.no_grad():\n            for batch_idx, (data, target) in enumerate(data_loader):\n                label = target[..., :args.output_dim]\n                output = model(data, target, teacher_forcing_ratio=0)\n                y_true.append(label)\n                y_pred.append(output)\n        y_pred = torch.cat(y_pred, dim=0)\n        y_pred = y_pred.cpu().numpy()\n\n        return y_pred\n\n    @staticmethod\n    def _compute_sampling_threshold(global_step, k):\n        \"\"\"\n        Computes the sampling probability for scheduled sampling using inverse sigmoid.\n        :param global_step:\n        :param k:\n        :return:\n        \"\"\"\n        return k / (k + math.exp(global_step / k))\n\n\ndef get_dataloader_AGCRN(data_loader, batchsize, tod=False, dow=False, weather=False, single=True):\n    # split data\n    train_closeness, val_closeness = SplitData.split_data(\n        data_loader.train_closeness, [0.9, 0.1])\n    train_period, val_period = SplitData.split_data(\n        data_loader.train_period, [0.9, 0.1])\n    train_trend, val_trend = SplitData.split_data(\n        data_loader.train_trend, [0.9, 0.1])\n    train_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\n\n    # T, N, D, 1 -> T, D, N, 1\n    if data_loader.period_len > 0 and data_loader.trend_len > 0:\n        train_x = np.concatenate(\n            [train_trend, train_period, train_closeness], axis=2).transpose([0, 2, 1, 3])\n        val_x = np.concatenate(\n            [val_trend, val_period, val_closeness], axis=2).transpose([0, 2, 1, 3])\n        test_x = np.concatenate([data_loader.test_trend, data_loader.test_period, data_loader.test_closeness],\n                                axis=2).transpose([0, 2, 1, 3])\n    else:\n        train_x = train_closeness.transpose([0, 2, 1, 3])\n        val_x = val_closeness.transpose([0, 2, 1, 3])\n        test_x = data_loader.test_closeness.transpose([0, 2, 1, 3])\n\n    train_y = train_y[:, np.newaxis]\n    val_y = val_y[:, np.newaxis]\n    test_y = data_loader.test_y[:, np.newaxis]\n\n    print('Train: ', train_x.shape, train_y.shape)\n    print('Val: ', val_x.shape, val_y.shape)\n    print('Test: ', test_x.shape, test_y.shape)\n    ############## get dataloader ######################\n    train_dataloader = data_loader_torch(\n        train_x, train_y, batchsize, shuffle=True, drop_last=True)\n    if len(train_x) == 0:\n        val_dataloader = None\n    else:\n        val_dataloader = data_loader_torch(\n            val_x, val_y, batchsize, shuffle=False, drop_last=True)\n    test_dataloader = data_loader_torch(\n        test_x, test_y, batchsize, shuffle=False, drop_last=False)\n    return train_dataloader, val_dataloader, test_dataloader\n\n\ndef data_loader_torch(X, Y, batch_size, shuffle=True, drop_last=True):\n    cuda = True if torch.cuda.is_available() else False\n    TensorFloat = torch.cuda.FloatTensor if cuda else torch.FloatTensor\n    X, Y = TensorFloat(X), TensorFloat(Y)\n    data = torch.utils.data.TensorDataset(X, Y)\n    dataloader = torch.utils.data.DataLoader(data, batch_size=batch_size,\n                                             shuffle=shuffle, drop_last=drop_last)\n    return dataloader\n\n\ndef get_logger(root, name=None, debug=True):\n    #when debug is true, show DEBUG and INFO in screen\n    #when debug is false, show DEBUG in file and info in both screen&file\n    #INFO will always be in screen\n    # create a logger\n    logger = logging.getLogger(name)\n    #critical > error > warning > info > debug > notset\n    logger.setLevel(logging.DEBUG)\n\n    # define the formate\n    formatter = logging.Formatter('%(asctime)s: %(message)s', \"%Y-%m-%d %H:%M\")\n    # create another handler for output log to console\n    console_handler = logging.StreamHandler()\n    if debug:\n        console_handler.setLevel(logging.DEBUG)\n    else:\n        console_handler.setLevel(logging.INFO)\n        # create a handler for write log to file\n        logfile = os.path.join(root, 'run.log')\n        print('Creat Log File in: ', logfile)\n        file_handler = logging.FileHandler(logfile, mode='w')\n        file_handler.setLevel(logging.DEBUG)\n        file_handler.setFormatter(formatter)\n    console_handler.setFormatter(formatter)\n    # add Handler to logger\n    logger.addHandler(console_handler)\n    if not debug:\n        logger.addHandler(file_handler)\n    return logger\n"
  },
  {
    "path": "UCTB/utils/utils_ASTGCN.py",
    "content": "\nimport os\nfrom time import time\nimport numpy as np\nimport shutil\n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.utils.data\n\nfrom UCTB.preprocess import SplitData\n# from tensorboardX import SummaryWriter\n\nfrom UCTB.train.LossFunction import masked_mape, masked_mae, masked_rmse, masked_mse\n\n\ndef load_data(data_loader, DEVICE, batch_size, shuffle=True):\n    '''\n    这个是为PEMS的数据准备的函数\n    将x,y都处理成归一化到[-1,1]之前的数据;\n    每个样本同时包含所有监测点的数据，所以本函数构造的数据输入时空序列预测模型；\n    该函数会把hour, day, week的时间串起来；\n    注： 从文件读入的数据，x是最大最小归一化的，但是y是真实值\n    这个函数转为mstgcn，astgcn设计，返回的数据x都是通过减均值除方差进行归一化的，y都是真实值\n    :param graph_signal_matrix_filename: str\n    :param num_of_hours: int\n    :param num_of_days: int\n    :param num_of_weeks: int\n    :param DEVICE:\n    :param batch_size: int\n    :return:\n    three DataLoaders, each dataloader contains:\n    test_x_tensor: (B, N_nodes, in_feature, T_input)\n    test_decoder_input_tensor: (B, N_nodes, T_output)\n    test_target_tensor: (B, N_nodes, T_output)\n\n    '''\n    # split data\n    train_closeness, val_closeness = SplitData.split_data(\n        data_loader.train_closeness, [0.9, 0.1])\n    train_period, val_period = SplitData.split_data(\n        data_loader.train_period, [0.9, 0.1])\n    train_trend, val_trend = SplitData.split_data(\n        data_loader.train_trend, [0.9, 0.1])\n    train_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\n\n    train_x = np.concatenate(\n        [train_trend, train_period, train_closeness], axis=2).transpose([0, 1, 3, 2])\n    train_target = train_y\n\n    val_x = np.concatenate(\n        [val_trend, val_period, val_closeness], axis=2).transpose([0, 1, 3, 2])\n    val_target = val_y\n\n    test_x = np.concatenate([data_loader.test_trend, data_loader.test_period,\n                            data_loader.test_closeness], axis=2).transpose([0, 1, 3, 2])\n    test_target = data_loader.test_y\n\n\n\n    print(\"train_x\", train_x.shape)\n    print(\"val_x\", val_x.shape)\n    print(\"test_x\", test_x.shape)\n\n    # ------- train_loader -------\n    train_x_tensor = torch.from_numpy(train_x).type(\n        torch.FloatTensor).to(DEVICE)  # (B, N, F, T)\n    train_target_tensor = torch.from_numpy(train_target).type(\n        torch.FloatTensor).to(DEVICE)  # (B, N, T)\n\n    train_dataset = torch.utils.data.TensorDataset(\n        train_x_tensor, train_target_tensor)\n\n    train_loader = torch.utils.data.DataLoader(\n        train_dataset, batch_size=batch_size, shuffle=shuffle)\n\n    # ------- val_loader -------\n    val_x_tensor = torch.from_numpy(val_x).type(\n        torch.FloatTensor).to(DEVICE)  # (B, N, F, T)\n    val_target_tensor = torch.from_numpy(val_target).type(\n        torch.FloatTensor).to(DEVICE)  # (B, N, T)\n\n    val_dataset = torch.utils.data.TensorDataset(\n        val_x_tensor, val_target_tensor)\n\n    val_loader = torch.utils.data.DataLoader(\n        val_dataset, batch_size=batch_size, shuffle=False)\n\n    # ------- test_loader -------\n    test_x_tensor = torch.from_numpy(test_x).type(\n        torch.FloatTensor).to(DEVICE)  # (B, N, F, T)\n    test_target_tensor = torch.from_numpy(test_target).type(\n        torch.FloatTensor).to(DEVICE)  # (B, N, T)\n\n    test_dataset = torch.utils.data.TensorDataset(\n        test_x_tensor, test_target_tensor)\n\n    test_loader = torch.utils.data.DataLoader(\n        test_dataset, batch_size=batch_size, shuffle=False)\n\n    # print\n    print('train:', train_x_tensor.size(), train_target_tensor.size())\n    print('val:', val_x_tensor.size(), val_target_tensor.size())\n    print('test:', test_x_tensor.size(), test_target_tensor.size())\n\n    return train_loader, train_target_tensor, val_loader, val_target_tensor, test_loader, test_target_tensor\n\n\ndef train_main(training_config, params_path, DEVICE, net, val_loader, train_loader, graph_signal_matrix_filename):\n    learning_rate = float(training_config['learning_rate'])\n    epochs = int(training_config['epochs'])\n    start_epoch = int(training_config['start_epoch'])\n    batch_size = int(training_config['batch_size'])\n    num_of_weeks = int(training_config['num_of_weeks'])\n    num_of_days = int(training_config['num_of_days'])\n    num_of_hours = int(training_config['num_of_hours'])\n    time_strides = num_of_hours\n    nb_chev_filter = int(training_config['nb_chev_filter'])\n    nb_time_filter = int(training_config['nb_time_filter'])\n    in_channels = int(training_config['in_channels'])\n    nb_block = int(training_config['nb_block'])\n    K = int(training_config['K'])\n    loss_function = training_config['loss_function']\n    metric_method = training_config['metric_method']\n    missing_value = float(training_config['missing_value'])\n    if (start_epoch == 0) and (not os.path.exists(params_path)):\n        os.makedirs(params_path)\n        print('create params directory %s' % (params_path))\n    elif (start_epoch == 0) and (os.path.exists(params_path)):\n        shutil.rmtree(params_path)\n        os.makedirs(params_path)\n        print('delete the old one and create params directory %s' % (params_path))\n    elif (start_epoch > 0) and (os.path.exists(params_path)):\n        print('train from params directory %s' % (params_path))\n    else:\n        raise SystemExit('Wrong type of model!')\n\n    print('param list:')\n    print('CUDA\\t', DEVICE)\n    print('in_channels\\t', in_channels)\n    print('nb_block\\t', nb_block)\n    print('nb_chev_filter\\t', nb_chev_filter)\n    print('nb_time_filter\\t', nb_time_filter)\n    print('time_strides\\t', time_strides)\n    print('batch_size\\t', batch_size)\n    print('graph_signal_matrix_filename\\t', graph_signal_matrix_filename)\n    print('start_epoch\\t', start_epoch)\n    print('epochs\\t', epochs)\n    masked_flag = 0\n    criterion = nn.L1Loss().to(DEVICE)\n    criterion_masked = masked_mae\n    if loss_function == 'masked_mse':\n        criterion_masked = masked_mse  # nn.MSELoss().to(DEVICE)\n        masked_flag = 1\n    elif loss_function == 'masked_mae':\n        criterion_masked = masked_mae\n        masked_flag = 1\n    elif loss_function == 'mae':\n        criterion = nn.L1Loss().to(DEVICE)\n        masked_flag = 0\n    elif loss_function == 'rmse':\n        criterion = nn.MSELoss().to(DEVICE)\n        masked_flag = 0\n    optimizer = optim.Adam(net.parameters(), lr=learning_rate)\n    # sw = SummaryWriter(logdir=params_path, flush_secs=5)\n    print(net)\n\n    print('Net\\'s state_dict:')\n    total_param = 0\n    for param_tensor in net.state_dict():\n        print(param_tensor, '\\t', net.state_dict()[param_tensor].size())\n        total_param += np.prod(net.state_dict()[param_tensor].size())\n    print('Net\\'s total params:', total_param)\n\n    print('Optimizer\\'s state_dict:')\n    for var_name in optimizer.state_dict():\n        print(var_name, '\\t', optimizer.state_dict()[var_name])\n\n    global_step = 0\n    best_epoch = 0\n    best_val_loss = np.inf\n\n    start_time = time()\n\n    if start_epoch > 0:\n\n        params_filename = os.path.join(\n            params_path, 'epoch_%s.params' % start_epoch)\n\n        net.load_state_dict(torch.load(params_filename))\n\n        print('start epoch:', start_epoch)\n\n        print('load weight from: ', params_filename)\n\n    # train model\n    for epoch in range(start_epoch, epochs):\n\n        params_filename = os.path.join(params_path, 'epoch_%s.params' % epoch)\n\n        if masked_flag:\n            val_loss = compute_val_loss_mstgcn(\n                net, val_loader, criterion_masked, masked_flag, missing_value, epoch)\n        else:\n            val_loss = compute_val_loss_mstgcn(\n                net, val_loader, criterion, masked_flag, missing_value, epoch)\n\n        if val_loss < best_val_loss:\n            best_val_loss = val_loss\n            best_epoch = epoch\n            torch.save(net.state_dict(), params_filename)\n            print('save parameters to file: %s' % params_filename)\n\n        net.train()  # ensure dropout layers are in train mode\n\n        for batch_index, batch_data in enumerate(train_loader):\n\n            encoder_inputs, labels = batch_data\n\n            optimizer.zero_grad()\n\n            outputs = net(encoder_inputs)\n\n            if masked_flag:\n                loss = criterion_masked(outputs, labels, missing_value)\n            else:\n                loss = criterion(outputs, labels)\n\n            loss.backward()\n\n            optimizer.step()\n\n            training_loss = loss.item()\n\n            global_step += 1\n\n            # sw.add_scalar('training_loss', training_loss, global_step)\n\n            if global_step % 10 == 0:\n\n                print('global step: %s, training loss: %.2f, time: %.2fs' %\n                      (global_step, training_loss, time() - start_time))\n\n    print('best epoch:', best_epoch)\n    return best_epoch\n\n\ndef predict_main(net, global_step, data_loader, data_target_tensor, params_path):\n    '''\n\n    :param global_step: int\n    :param data_loader: torch.utils.data.utils.DataLoader\n    :param data_target_tensor: tensor\n    :param mean: (1, 1, 3, 1)\n    :param std: (1, 1, 3, 1)\n    :param type: string\n    :return:\n    '''\n\n    params_filename = os.path.join(\n        params_path, 'epoch_%s.params' % global_step)\n    print('load weight from:', params_filename)\n\n    net.load_state_dict(torch.load(params_filename))\n\n    net.train(False)  # ensure dropout layers are in test mode\n\n    with torch.no_grad():\n\n        data_target_tensor = data_target_tensor.cpu().numpy()\n\n        loader_length = len(data_loader)  # nb of batch\n\n        prediction = []  # 存储所有batch的output\n\n        input = []  # 存储所有batch的input\n\n        for batch_index, batch_data in enumerate(data_loader):\n\n            encoder_inputs, labels = batch_data\n\n            # (batch, T', 1)\n            input.append(encoder_inputs[:, :, 0:1].cpu().numpy())\n\n            outputs = net(encoder_inputs)\n\n            prediction.append(outputs.detach().cpu().numpy())\n\n            if batch_index % 100 == 0:\n                print('predicting data set batch %s / %s' %\n                      (batch_index + 1, loader_length))\n\n        input = np.concatenate(input, 0)\n\n        prediction = np.concatenate(prediction, 0)  # (batch, T', 1)\n\n        return prediction\n        \n\n\ndef compute_val_loss_mstgcn(net, val_loader, criterion,  masked_flag,missing_value, epoch, limit=None):\n    '''\n    for rnn, compute mean loss on validation set\n    :param net: model\n    :param val_loader: torch.utils.data.utils.DataLoader\n    :param criterion: torch.nn.MSELoss\n    :param sw: tensorboardX.SummaryWriter\n    :param global_step: int, current global_step\n    :param limit: int,\n    :return: val_loss\n    '''\n\n    net.train(False)  # ensure dropout layers are in evaluation mode\n\n    with torch.no_grad():\n\n        val_loader_length = len(val_loader)  # nb of batch\n\n        tmp = []  # 记录了所有batch的loss\n\n        for batch_index, batch_data in enumerate(val_loader):\n            encoder_inputs, labels = batch_data\n            outputs = net(encoder_inputs)\n            if masked_flag:\n                loss = criterion(outputs, labels, missing_value)\n            else:\n                loss = criterion(outputs, labels)\n\n            tmp.append(loss.item())\n            if batch_index % 100 == 0:\n                print('validation batch %s / %s, loss: %.2f' % (batch_index + 1, val_loader_length, loss.item()))\n            if (limit is not None) and batch_index >= limit:\n                break\n\n        validation_loss = sum(tmp) / len(tmp)\n        # sw.add_scalar('validation_loss', validation_loss, epoch)\n    return validation_loss\n\n"
  },
  {
    "path": "UCTB/utils/utils_GMAN.py",
    "content": "import time\nimport math\nimport os\nfrom UCTB.model.GMAN import GMAN\nfrom gensim.models import Word2Vec\nimport datetime\nfrom UCTB.preprocess import SplitData\nfrom UCTB.train.LossFunction import mae_loss\nimport tensorflow as tf\nimport networkx as nx\nimport numpy as np\n\n\ndef build_model(log, time_fitness, trainX, args, SE):\n    log_string(log, 'compiling model...')\n    T = time_fitness\n    print(\"time_fitness: \", T)\n    num_train, _, N = trainX.shape\n    X, TE, label, is_training = placeholder(args.P, args.Q, N)\n    global_step = tf.Variable(0, trainable=False)\n    bn_momentum = tf.compat.v1.train.exponential_decay(\n        0.5, global_step,\n        decay_steps=args.decay_epoch * num_train // args.batch_size,\n        decay_rate=0.5, staircase=True)\n    bn_decay = tf.minimum(0.99, 1 - bn_momentum)\n\n    pred = GMAN(\n        X, TE, SE, args.P, args.Q, T, args.L, args.K, args.d,\n        bn=True, bn_decay=bn_decay, is_training=is_training)\n    \n    loss = mae_loss(pred, label)\n    tf.compat.v1.add_to_collection('pred', pred)\n    tf.compat.v1.add_to_collection('loss', loss)\n    learning_rate = tf.compat.v1.train.exponential_decay(\n        args.learning_rate, global_step,\n        decay_steps=args.decay_epoch * num_train // args.batch_size,\n        decay_rate=0.7, staircase=True)\n    learning_rate = tf.maximum(learning_rate, 1e-5)\n    optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate)\n    train_op = optimizer.minimize(loss, global_step=global_step)\n    parameters = 0\n    for variable in tf.compat.v1.trainable_variables():\n        parameters += np.product([x.value for x in variable.get_shape()])\n    log_string(log, 'trainable parameters: {:,}'.format(parameters))\n    log_string(log, 'model compiled!')\n    saver = tf.compat.v1.train.Saver()\n    config = tf.compat.v1.ConfigProto()\n    config.gpu_options.allow_growth = True\n    sess = tf.compat.v1.Session(config=config)\n    sess.run(tf.compat.v1.global_variables_initializer())\n\n    return X, TE, label, is_training, saver, sess, train_op, loss, pred\n\n\ndef Train(log, args, trainX, trainY, trainTE, valX, valTE, valY, X, TE, label, is_training, saver, sess, train_op, loss, pred):\n\n    log_string(log, '**** training model ****')\n    num_train, _, N = trainX.shape\n    num_val = valX.shape[0]\n    wait = 0\n    val_loss_min = np.inf\n    for epoch in range(args.max_epoch):\n        if wait >= args.patience:\n            log_string(log, 'early stop at epoch: %04d' % (epoch))\n            break\n        # shuffle\n        permutation = np.random.permutation(num_train)\n        trainX = trainX[permutation]\n        trainTE = trainTE[permutation]\n        trainY = trainY[permutation]\n        # train loss\n        start_train = time.time()\n        train_loss = 0\n        num_batch = math.ceil(num_train / args.batch_size)\n        for batch_idx in range(num_batch):\n            start_idx = batch_idx * args.batch_size\n            end_idx = min(num_train, (batch_idx + 1) * args.batch_size)\n            feed_dict = {\n                X: trainX[start_idx: end_idx],\n                TE: trainTE[start_idx: end_idx],\n                label: trainY[start_idx: end_idx],\n                is_training: True}\n            # print(train_op.size())\n            _, loss_batch = sess.run([train_op, loss], feed_dict=feed_dict)\n            train_loss += loss_batch * (end_idx - start_idx)\n        train_loss /= num_train\n        end_train = time.time()\n        # val loss\n        start_val = time.time()\n        val_loss = 0\n        num_batch = math.ceil(num_val / args.batch_size)\n        for batch_idx in range(num_batch):\n            start_idx = batch_idx * args.batch_size\n            end_idx = min(num_val, (batch_idx + 1) * args.batch_size)\n            feed_dict = {\n                X: valX[start_idx: end_idx],\n                TE: valTE[start_idx: end_idx],\n                label: valY[start_idx: end_idx],\n                is_training: False}\n            loss_batch = sess.run(loss, feed_dict=feed_dict)\n            val_loss += loss_batch * (end_idx - start_idx)\n        val_loss /= num_val\n        end_val = time.time()\n        log_string(\n            log,\n            '%s | epoch: %04d/%d, training time: %.1fs, inference time: %.1fs' %\n            (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), epoch + 1,\n             args.max_epoch, end_train - start_train, end_val - start_val))\n        log_string(\n            log, 'train loss: %.4f, val_loss: %.4f' % (train_loss, val_loss))\n        if val_loss <= val_loss_min:\n            log_string(\n                log,\n                'val loss decrease from %.4f to %.4f, saving model to %s' %\n                (val_loss_min, val_loss, args.model_file))\n            wait = 0\n            val_loss_min = val_loss\n            saver.save(sess, args.model_file)\n        else:\n            wait += 1\n    log_string(log, '**** testing model ****')\n    log_string(log, 'loading model from %s' % args.model_file)\n    saver = tf.compat.v1.train.import_meta_graph(args.model_file + '.meta')\n    saver.restore(sess, args.model_file)\n    log_string(log, 'model restored!')\n    log_string(log, 'evaluating...')\n\n    trainPred = []\n    num_batch = math.ceil(num_train / args.batch_size)\n    for batch_idx in range(num_batch):\n        start_idx = batch_idx * args.batch_size\n        end_idx = min(num_train, (batch_idx + 1) * args.batch_size)\n        feed_dict = {\n            X: trainX[start_idx: end_idx],\n            TE: trainTE[start_idx: end_idx],\n            is_training: False}\n        pred_batch = sess.run(pred, feed_dict=feed_dict)\n        trainPred.append(pred_batch)\n    trainPred = np.concatenate(trainPred, axis=0)\n\n    valPred = []\n    num_batch = math.ceil(num_val / args.batch_size)\n    for batch_idx in range(num_batch):\n        start_idx = batch_idx * args.batch_size\n        end_idx = min(num_val, (batch_idx + 1) * args.batch_size)\n        feed_dict = {\n            X: valX[start_idx: end_idx],\n            TE: valTE[start_idx: end_idx],\n            is_training: False}\n        pred_batch = sess.run(pred, feed_dict=feed_dict)\n        valPred.append(pred_batch)\n    valPred = np.concatenate(valPred, axis=0)\n\n    return trainPred, valPred\n\n\ndef Test(log, args, testX, testTE, X, TE, is_training, sess, pred):\n    num_test = testX.shape[0]\n    testPred = []\n    num_batch = math.ceil(num_test / args.batch_size)\n    start_test = time.time()\n    for batch_idx in range(num_batch):\n        start_idx = batch_idx * args.batch_size\n        end_idx = min(num_test, (batch_idx + 1) * args.batch_size)\n        feed_dict = {\n            X: testX[start_idx: end_idx],\n            TE: testTE[start_idx: end_idx],\n            is_training: False}\n        pred_batch = sess.run(pred, feed_dict=feed_dict)\n        testPred.append(pred_batch)\n    end_test = time.time()\n    testPred = np.concatenate(testPred, axis=0)\n\n    log_string(log, 'Test time: %.1fmin' % ((end_test - start_test) / 60))\n    sess.close()\n    log.close()\n\n    return testPred\n\n\ndef load_data(args, data_loader):\n    # split data\n    train_closeness, val_closeness = SplitData.split_data(\n        data_loader.train_closeness, [0.9, 0.1])\n    train_period, val_period = SplitData.split_data(\n        data_loader.train_period, [0.9, 0.1])\n    train_trend, val_trend = SplitData.split_data(\n        data_loader.train_trend, [0.9, 0.1])\n    train_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\n    print(train_y.shape)\n\n    trainY = train_y.reshape([train_y.shape[0], 1, data_loader.station_number])\n    valY = val_y.reshape([val_y.shape[0], 1, data_loader.station_number])\n    testY = data_loader.test_y.reshape(\n        [data_loader.test_y.shape[0], 1, data_loader.station_number])\n\n    # T, num_node, dimension -> T, dimension, num_node\n    if data_loader.period_len > 0 and data_loader.trend_len > 0:\n        trainX = np.concatenate(\n            [train_trend, train_period, train_closeness], axis=2).squeeze().transpose([0, 2, 1])\n        print(trainX.shape)\n        valX = np.concatenate(\n            [val_trend, val_period, val_closeness], axis=2).squeeze().transpose([0, 2, 1])\n        testX = np.concatenate([data_loader.test_trend, data_loader.test_period, data_loader.test_closeness],\n                               axis=2).squeeze().transpose([0, 2, 1])\n    else:\n        trainX = train_closeness.squeeze().transpose([0, 2, 1])\n        valX = val_closeness.squeeze().transpose([0, 2, 1])\n        testX = data_loader.test_closeness.squeeze().transpose([0, 2, 1])\n\n\n    # spatial embedding\n    f = open(args.SE_file, mode='r')\n    lines = f.readlines()\n    temp = lines[0].split(' ')\n    N, dims = int(temp[0]), int(temp[1])\n    SE = np.zeros(shape=(N, dims), dtype=np.float32)\n    for line in lines[1:]:\n        temp = line.split(' ')\n        index = int(temp[0])\n        SE[index] = temp[1:]\n\n    train_steps, val_steps, test_steps = len(trainX), len(valX), len(testX)\n    # print(\"train_steps\",train_steps)\n    # print(\"test_steps\",test_steps)\n    # print(\"val_steps\",val_steps)\n\n    # temporal embedding\n    time_fitness = data_loader.dataset.time_fitness\n    time_delta = datetime.timedelta(minutes=time_fitness)\n    try:\n        start_time = datetime.datetime.strptime(\n            data_loader.dataset.time_range[0], \"%Y-%m-%d\")\n    except:\n        start_time = datetime.datetime.strptime(\n            data_loader.dataset.time_range[0], \"%Y-%m-%d %H:%M:%S\")\n\n    Time = [start_time + i *\n            time_delta for i in range(train_steps + test_steps + val_steps + args.P)]\n\n    def get_attr(object, attr):\n        return np.array([eval(\"item.{}\".format(attr)) for item in object])\n\n    print(data_loader.dataset.time_range[0])\n    dayofweek = np.reshape(get_attr(Time, \"weekday()\"), newshape=(-1, 1))\n    # timeofday = (Time.hour * 3600 + Time.minute * 60 + Time.second) \\\n    #             // Time.freq.delta.total_seconds()\n    timeofday = (get_attr(Time, \"hour\") * 3600 + get_attr(Time, \"minute\") * 60 + get_attr(Time, \"second\")) \\\n        // (86400)\n    timeofday = np.reshape(timeofday, newshape=(-1, 1))\n    Time = np.concatenate((dayofweek, timeofday), axis=-1)\n    # train/val/test\n    train = Time[: train_steps + args.P]\n    val = Time[train_steps: train_steps + val_steps + args.P]\n    test = Time[train_steps + val_steps:]\n    # shape = (num_sample, P + Q, 2)\n    trainTE = seq2instance(train, args.P, args.Q)\n    trainTE = np.concatenate(trainTE, axis=1).astype(np.int32)\n    valTE = seq2instance(val, args.P, args.Q)\n    valTE = np.concatenate(valTE, axis=1).astype(np.int32)\n    testTE = seq2instance(test, args.P, args.Q)\n    testTE = np.concatenate(testTE, axis=1).astype(np.int32)\n    \n    return (trainX, trainTE, trainY, valX, valTE, valY, testX, testTE, testY,\n            SE, time_fitness)\n\n\ndef placeholder(P, Q, N):\n    X = tf.compat.v1.placeholder(shape=(None, P, N), dtype=tf.float32)\n    TE = tf.compat.v1.placeholder(shape=(None, P + Q, 2), dtype=tf.int32)\n    label = tf.compat.v1.placeholder(shape=(None, Q, N), dtype=tf.float32)\n    is_training = tf.compat.v1.placeholder(shape=(), dtype=tf.bool)\n    return X, TE, label, is_training\n\n\ndef graph_to_adj_files(adjacent_matrix, Adj_file):\n    with open(Adj_file, \"w\") as fp:\n        adj_list = []\n        print(adjacent_matrix.shape)\n        for i in range(adjacent_matrix.shape[0]):\n            for j in range(adjacent_matrix.shape[1]):\n                adj_list.append(\"{} {} {:.6f}\\n\".format(\n                    i, j, adjacent_matrix[i, j]))\n        fp.writelines(adj_list)\n\n\ndef read_graph(edgelist):\n    G = nx.read_edgelist(\n        edgelist, nodetype=int, data=(('weight', float),),\n        create_using=nx.DiGraph())\n    return G\n\n\ndef learn_embeddings(walks, dimensions, output_file, epochs):\n    walks = [list(map(str, walk)) for walk in walks]\n    model = Word2Vec(\n        walks, vector_size=dimensions, window=10, min_count=0, sg=1,\n        workers=8, epochs=epochs)\n    model.wv.save_word2vec_format(output_file)\n    return\n\n\ndef seq2instance(data, P, Q):\n    num_step, dims = data.shape\n    num_sample = num_step - P - Q + 1\n    x = np.zeros(shape=(num_sample, P, dims))\n    y = np.zeros(shape=(num_sample, Q, dims))\n    for i in range(num_sample):\n        x[i] = data[i: i + P]\n        y[i] = data[i + P: i + P + Q]\n    return x, y\n\n# log string\ndef log_string(log, string):\n    log.write(string + '\\n')\n    log.flush()\n    print(string)\n"
  },
  {
    "path": "UCTB/utils/utils_GraphWaveNet.py",
    "content": "import os\nimport time\nimport torch\nimport torch.nn as nn\nimport numpy as np\nimport torch.optim as optim\nfrom UCTB.preprocess.preprocessor import SplitData\nfrom UCTB.model.GraphWaveNet import *\nfrom UCTB.train.LossFunction import masked_mape, masked_mae, masked_rmse\n\n\nclass trainer():\n    def __init__(self, in_dim, seq_length, num_nodes, nhid , dropout, lrate, wdecay, device, supports, gcn_bool, addaptadj, aptinit):\n        self.model = gwnet(device, num_nodes, dropout, supports=supports, gcn_bool=gcn_bool, addaptadj=addaptadj, aptinit=aptinit, in_dim=in_dim, out_dim=seq_length, residual_channels=nhid, dilation_channels=nhid, skip_channels=nhid * 8, end_channels=nhid * 16)\n        self.model.to(device)\n        self.optimizer = optim.Adam(self.model.parameters(), lr=lrate, weight_decay=wdecay)\n        self.loss = masked_mae\n        self.clip = 5\n\n    def train(self, input, real_val):\n        self.model.train()\n        self.optimizer.zero_grad()\n        input = nn.functional.pad(input,(1,0,0,0))\n        # print(\"input\",input.shape)\n        output = self.model(input)\n        output = output.transpose(1,3)\n        # print(\"ouput\",output.shape)\n        #output = [batch_size,12,num_nodes,1]\n        real = torch.unsqueeze(real_val,dim=1)\n        predict = output\n\n        loss = self.loss(predict, real, 0.0)\n        loss.backward()\n        if self.clip is not None:\n            torch.nn.utils.clip_grad_norm_(self.model.parameters(), self.clip)\n        self.optimizer.step()\n        mape = masked_mape(predict,real,0.0).item()\n        rmse = masked_rmse(predict,real,0.0).item()\n        return loss.item(),mape,rmse\n\n    def eval(self, input, real_val):\n        self.model.eval()\n        input = nn.functional.pad(input,(1,0,0,0))\n        output = self.model(input)\n        output = output.transpose(1,3)\n        #output = [batch_size,12,num_nodes,1]\n        real = torch.unsqueeze(real_val,dim=1)\n        predict = output\n        loss = self.loss(predict, real, 0.0)\n        mape = masked_mape(predict,real,0.0).item()\n        rmse = masked_rmse(predict,real,0.0).item()\n        return loss.item(),mape,rmse\n\n\ndef Training(args, dataloader,  device, engine):\n    print(\"start training...\", flush=True)\n    his_loss = []\n    val_time = []\n    train_time = []\n    for i in range(1, args.epochs + 1):\n        train_loss = []\n        train_mape = []\n        train_rmse = []\n        t1 = time.time()\n        dataloader['train_loader'].shuffle()\n        for iter, (x, y) in enumerate(dataloader['train_loader'].get_iterator()):\n            trainx = torch.Tensor(x).to(device)\n            trainx = trainx.transpose(1, 3)\n            trainy = torch.Tensor(y).to(device)\n            trainy = trainy.transpose(1, 3)\n            metrics = engine.train(trainx, trainy[:, 0, :, :])\n            train_loss.append(metrics[0])\n            train_mape.append(metrics[1])\n            train_rmse.append(metrics[2])\n            if iter % args.print_every == 0:\n                log = 'Iter: {:03d}, Train Loss: {:.4f}, Train MAPE: {:.4f}, Train RMSE: {:.4f}'\n                print(log.format(iter, train_loss[-1], train_mape[-1], train_rmse[-1]), flush=True)\n        t2 = time.time()\n        train_time.append(t2 - t1)\n        # validation\n        valid_loss = []\n        valid_mape = []\n        valid_rmse = []\n\n        s1 = time.time()\n        for iter, (x, y) in enumerate(dataloader['val_loader'].get_iterator()):\n            testx = torch.Tensor(x).to(device)\n            testx = testx.transpose(1, 3)\n            testy = torch.Tensor(y).to(device)\n            testy = testy.transpose(1, 3)\n            metrics = engine.eval(testx, testy[:, 0, :, :])\n            valid_loss.append(metrics[0])\n            valid_mape.append(metrics[1])\n            valid_rmse.append(metrics[2])\n        s2 = time.time()\n        log = 'Epoch: {:03d}, Inference Time: {:.4f} secs'\n        print(log.format(i, (s2 - s1)))\n        val_time.append(s2 - s1)\n        mtrain_loss = np.mean(train_loss)\n        mtrain_mape = np.mean(train_mape)\n        mtrain_rmse = np.mean(train_rmse)\n\n        mvalid_loss = np.mean(valid_loss)\n        mvalid_mape = np.mean(valid_mape)\n        mvalid_rmse = np.mean(valid_rmse)\n        his_loss.append(mvalid_loss)\n\n        log = 'Epoch: {:03d}, Train Loss: {:.4f}, Train MAPE: {:.4f}, Train RMSE: {:.4f}, Valid Loss: {:.4f}, Valid MAPE: {:.4f}, Valid RMSE: {:.4f}, Training Time: {:.4f}/epoch'\n        print(log.format(i, mtrain_loss, mtrain_mape, mtrain_rmse, mvalid_loss, mvalid_mape, mvalid_rmse, (t2 - t1)),\n              flush=True)\n        torch.save(engine.model.state_dict(),\n                   os.path.join(args.save, \"epoch_\" + str(i) + \"_\" + str(round(mvalid_loss, 2)) + \".pth\"))\n    print(\"Average Training Time: {:.4f} secs/epoch\".format(np.mean(train_time)))\n    print(\"Average Inference Time: {:.4f} secs\".format(np.mean(val_time)))\n\n    return np.argmin(his_loss), his_loss[np.argmin(his_loss)]\n\ndef Test(args,dataloader,device,engine,epoch_id, loss_id):\n    # Test\n    engine.model.load_state_dict(torch.load(\n        os.path.join(args.save, \"epoch_\" + str(epoch_id + 1) + \"_\" + str(round(loss_id, 2)) + \".pth\")))\n\n    outputs = []\n    realy = torch.Tensor(dataloader['y_test']).to(device)\n    print(\"realy\", realy.shape)\n\n    realy = realy.transpose(1, 3)[:, 0, :, :]\n\n    for iter, (x, y) in enumerate(dataloader['test_loader'].get_iterator()):\n        testx = torch.Tensor(x).to(device)\n        testx = testx.transpose(1, 3)\n        with torch.no_grad():\n            preds = engine.model(testx).transpose(1, 3)\n        outputs.append(preds.squeeze())\n\n    yhat = torch.cat(outputs, dim=0).cpu().numpy()\n    yhat = yhat[:realy.size(0), ...]\n    realy = realy.cpu().numpy()\n\n    return yhat\n\nclass DataLoader(object):\n    def __init__(self, xs, ys, batch_size, pad_with_last_sample=True):\n        \"\"\"\n        :param xs:\n        :param ys:\n        :param batch_size:\n        :param pad_with_last_sample: pad with the last sample to make number of samples divisible to batch_size.\n        \"\"\"\n        self.batch_size = batch_size\n        self.current_ind = 0\n        if pad_with_last_sample:\n            num_padding = (batch_size - (len(xs) % batch_size)) % batch_size\n            x_padding = np.repeat(xs[-1:], num_padding, axis=0)\n            y_padding = np.repeat(ys[-1:], num_padding, axis=0)\n            xs = np.concatenate([xs, x_padding], axis=0)\n            ys = np.concatenate([ys, y_padding], axis=0)\n        self.size = len(xs)\n        self.num_batch = int(self.size // self.batch_size)\n        self.xs = xs\n        self.ys = ys\n\n    def shuffle(self):\n        permutation = np.random.permutation(self.size)\n        xs, ys = self.xs[permutation], self.ys[permutation]\n        self.xs = xs\n        self.ys = ys\n\n    def get_iterator(self):\n        self.current_ind = 0\n\n        def _wrapper():\n            while self.current_ind < self.num_batch:\n                start_ind = self.batch_size * self.current_ind\n                end_ind = min(self.size, self.batch_size * (self.current_ind + 1))\n                x_i = self.xs[start_ind: end_ind, ...]\n                y_i = self.ys[start_ind: end_ind, ...]\n                yield (x_i, y_i)\n                self.current_ind += 1\n\n        return _wrapper()\n\n\n\ndef load_dataset(uctb_data_loader, batch_size, valid_batch_size=None, test_batch_size=None):\n    # x_train (num_slots, time_steps, num_stations, input_dims)\n    # y_train (num_slots, time_steps, num_stations, input_dims)\n    data = {}\n\n    # split data\n    train_closeness, val_closeness = SplitData.split_data(uctb_data_loader.train_closeness, [0.9, 0.1])\n    train_period, val_period = SplitData.split_data(uctb_data_loader.train_period, [0.9, 0.1])\n    train_trend, val_trend = SplitData.split_data(uctb_data_loader.train_trend, [0.9, 0.1])\n    train_y, val_y = SplitData.split_data(uctb_data_loader.train_y, [0.9, 0.1])\n\n    # train_x = np.concatenate([train_trend, train_period, train_closeness],axis=2).transpose( # [0,3,1,2] [0,2,1,3]\n    if uctb_data_loader.period_len > 0 and uctb_data_loader.trend_len > 0:\n        data[\"x_train\"] = np.concatenate([train_trend, train_period, train_closeness], axis=2).transpose([0, 3, 1, 2])\n        data[\"x_val\"] = np.concatenate([val_trend, val_period, val_closeness], axis=2).transpose([0, 3, 1, 2])\n        data[\"x_test\"] = np.concatenate(\n            [uctb_data_loader.test_trend, uctb_data_loader.test_period, uctb_data_loader.test_closeness],\n            axis=2).transpose([0, 3, 1, 2])\n    else:\n        data[\"x_train\"] = train_closeness.transpose([0, 3, 1, 2])\n        data[\"x_val\"] = val_closeness.transpose([0, 3, 1, 2])\n        data[\"x_test\"] = uctb_data_loader.test_closeness.transpose([0, 3, 1, 2])\n\n    data[\"y_train\"] = train_y[:, np.newaxis]\n    data[\"y_val\"] = val_y[:, np.newaxis]\n    data[\"y_test\"] = uctb_data_loader.test_y[:, np.newaxis]\n\n    print(\"x_train\", data[\"x_train\"].shape)\n    print(\"y_train\", data[\"y_train\"].shape)\n    print(\"x_val\", data[\"x_val\"].shape)\n    print(\"y_val\", data[\"y_val\"].shape)\n    print(\"x_test\", data[\"x_test\"].shape)\n    print(\"y_test\", data[\"y_test\"].shape)\n\n\n\n    data['train_loader'] = DataLoader(data['x_train'], data['y_train'], batch_size)\n    data['val_loader'] = DataLoader(data['x_val'], data['y_val'], valid_batch_size)\n    data['test_loader'] = DataLoader(data['x_test'], data['y_test'], test_batch_size)\n    return data"
  },
  {
    "path": "UCTB/utils/utils_MTGNN.py",
    "content": "import pickle\nimport numpy as np\nimport os\nimport scipy.sparse as sp\nimport torch\nfrom scipy.sparse import linalg\nfrom torch.autograd import Variable\nimport torch.optim as optim\nfrom UCTB.preprocess.preprocessor import SplitData\nimport pdb\nimport torch.nn.functional as F\n\n\ndef normal_std(x):\n    return x.std() * np.sqrt((len(x) - 1.)/(len(x)))\nclass Trainer():\n    def __init__(self, model, lrate, wdecay, clip, step_size, seq_out_len, device, cl=True):\n        self.model = model\n        self.model.to(device)\n        self.optimizer = optim.Adam(self.model.parameters(), lr=lrate, weight_decay=wdecay)\n        self.loss = F.mse_loss\n        self.clip = clip\n        self.step = step_size\n        self.iter = 1\n        self.task_level = 1\n        self.seq_out_len = seq_out_len\n        self.cl = cl\n\n    def train(self, input, real_val, idx=None):\n        self.model.train()\n        self.optimizer.zero_grad()\n        output = self.model(input, idx=idx)\n        output = output.transpose(1,3)\n        real = torch.unsqueeze(real_val,dim=1)\n        predict = output\n        if self.iter%self.step==0 and self.task_level<=self.seq_out_len:\n            self.task_level +=1\n        if self.cl:\n            loss = self.loss(predict[:, :, :, :self.task_level], real[:, :, :, :self.task_level])\n        else:\n            loss = self.loss(predict, real)\n\n        loss.backward()\n\n        if self.clip is not None:\n            torch.nn.utils.clip_grad_norm_(self.model.parameters(), self.clip)\n\n        self.optimizer.step()\n        # mae = util.masked_mae(predict,real,0.0).item()\n        mape = masked_mape(predict,real).item()\n        rmse = masked_rmse(predict,real).item()\n        self.iter += 1\n        return loss.item(),mape,rmse\n\n    def eval(self, input, real_val):\n        self.model.eval()\n        output = self.model(input)\n        output = output.transpose(1,3)\n        real = torch.unsqueeze(real_val,dim=1)\n        predict = output\n        loss = self.loss(predict, real)\n        mape = masked_mape(predict,real).item()\n        rmse = masked_rmse(predict,real).item()\n        return loss.item(),mape,rmse\n    \nclass DataLoaderS(object):\n    # train and valid is the ratio of training set and validation set. test = 1 - train - valid\n    def __init__(self, file_name, train, valid, device, horizon, window, normalize=2):\n        self.P = window\n        self.h = horizon\n        fin = open(file_name)\n        self.rawdat = np.loadtxt(fin, delimiter=',')\n        self.dat = np.zeros(self.rawdat.shape)\n        self.n, self.m = self.dat.shape\n        self.normalize = 2\n        self.scale = np.ones(self.m)\n        self._normalized(normalize)\n        self._split(int(train * self.n), int((train + valid) * self.n), self.n)\n\n        self.scale = torch.from_numpy(self.scale).float()\n        tmp = self.test[1] * self.scale.expand(self.test[1].size(0), self.m)\n\n        self.scale = self.scale.to(device)\n        self.scale = Variable(self.scale)\n\n        self.rse = normal_std(tmp)\n        self.rae = torch.mean(torch.abs(tmp - torch.mean(tmp)))\n\n        self.device = device\n\n    def _normalized(self, normalize):\n        # normalized by the maximum value of entire matrix.\n\n        if (normalize == 0):\n            self.dat = self.rawdat\n\n        if (normalize == 1):\n            self.dat = self.rawdat / np.max(self.rawdat)\n\n        # normlized by the maximum value of each row(sensor).\n        if (normalize == 2):\n            for i in range(self.m):\n                self.scale[i] = np.max(np.abs(self.rawdat[:, i]))\n                self.dat[:, i] = self.rawdat[:, i] / np.max(np.abs(self.rawdat[:, i]))\n\n    def _split(self, train, valid, test):\n\n        train_set = range(self.P + self.h - 1, train)\n        valid_set = range(train, valid)\n        test_set = range(valid, self.n)\n        self.train = self._batchify(train_set, self.h)\n        self.valid = self._batchify(valid_set, self.h)\n        self.test = self._batchify(test_set, self.h)\n\n    def _batchify(self, idx_set, horizon):\n        n = len(idx_set)\n        X = torch.zeros((n, self.P, self.m))\n        Y = torch.zeros((n, self.m))\n        for i in range(n):\n            end = idx_set[i] - self.h + 1\n            start = end - self.P\n            X[i, :, :] = torch.from_numpy(self.dat[start:end, :])\n            Y[i, :] = torch.from_numpy(self.dat[idx_set[i], :])\n        return [X, Y]\n\n    def get_batches(self, inputs, targets, batch_size, shuffle=True):\n        length = len(inputs)\n        if shuffle:\n            index = torch.randperm(length)\n        else:\n            index = torch.LongTensor(range(length))\n        start_idx = 0\n        while (start_idx < length):\n            end_idx = min(length, start_idx + batch_size)\n            excerpt = index[start_idx:end_idx]\n            X = inputs[excerpt]\n            Y = targets[excerpt]\n            X = X.to(self.device)\n            Y = Y.to(self.device)\n            yield Variable(X), Variable(Y)\n            start_idx += batch_size\n\nclass DataLoaderM(object):\n    def __init__(self, xs, ys, batch_size, pad_with_last_sample=True):\n        \"\"\"\n        :param xs:\n        :param ys:\n        :param batch_size:\n        :param pad_with_last_sample: pad with the last sample to make number of samples divisible to batch_size.\n        \"\"\"\n        self.batch_size = batch_size\n        self.current_ind = 0\n        if pad_with_last_sample:\n            num_padding = (batch_size - (len(xs) % batch_size)) % batch_size\n            x_padding = np.repeat(xs[-1:], num_padding, axis=0)\n            y_padding = np.repeat(ys[-1:], num_padding, axis=0)\n            xs = np.concatenate([xs, x_padding], axis=0)\n            ys = np.concatenate([ys, y_padding], axis=0)\n        self.size = len(xs)\n        self.num_batch = int(self.size // self.batch_size)\n        self.xs = xs\n        self.ys = ys\n\n    def shuffle(self):\n        permutation = np.random.permutation(self.size)\n        xs, ys = self.xs[permutation], self.ys[permutation]\n        self.xs = xs\n        self.ys = ys\n\n    def get_iterator(self):\n        self.current_ind = 0\n        def _wrapper():\n            while self.current_ind < self.num_batch:\n                start_ind = self.batch_size * self.current_ind\n                end_ind = min(self.size, self.batch_size * (self.current_ind + 1))\n                x_i = self.xs[start_ind: end_ind, ...]\n                y_i = self.ys[start_ind: end_ind, ...]\n                yield (x_i, y_i)\n                self.current_ind += 1\n\n        return _wrapper()\n\nclass StandardScaler():\n    \"\"\"\n    Standard the input\n    \"\"\"\n    def __init__(self, mean, std):\n        self.mean = mean\n        self.std = std\n    def transform(self, data):\n        return (data - self.mean) / self.std\n    def inverse_transform(self, data):\n        return (data * self.std) + self.mean\n\n\ndef sym_adj(adj):\n    \"\"\"Symmetrically normalize adjacency matrix.\"\"\"\n    adj = sp.coo_matrix(adj)\n    rowsum = np.array(adj.sum(1))\n    d_inv_sqrt = np.power(rowsum, -0.5).flatten()\n    d_inv_sqrt[np.isinf(d_inv_sqrt)] = 0.\n    d_mat_inv_sqrt = sp.diags(d_inv_sqrt)\n    return adj.dot(d_mat_inv_sqrt).transpose().dot(d_mat_inv_sqrt).astype(np.float32).todense()\n\ndef asym_adj(adj):\n    \"\"\"Asymmetrically normalize adjacency matrix.\"\"\"\n    adj = sp.coo_matrix(adj)\n    rowsum = np.array(adj.sum(1)).flatten()\n    d_inv = np.power(rowsum, -1).flatten()\n    d_inv[np.isinf(d_inv)] = 0.\n    d_mat= sp.diags(d_inv)\n    return d_mat.dot(adj).astype(np.float32).todense()\n\ndef calculate_normalized_laplacian(adj):\n    \"\"\"\n    # L = D^-1/2 (D-A) D^-1/2 = I - D^-1/2 A D^-1/2\n    # D = diag(A 1)\n    :param adj:\n    :return:\n    \"\"\"\n    adj = sp.coo_matrix(adj)\n    d = np.array(adj.sum(1))\n    d_inv_sqrt = np.power(d, -0.5).flatten()\n    d_inv_sqrt[np.isinf(d_inv_sqrt)] = 0.\n    d_mat_inv_sqrt = sp.diags(d_inv_sqrt)\n    normalized_laplacian = sp.eye(adj.shape[0]) - adj.dot(d_mat_inv_sqrt).transpose().dot(d_mat_inv_sqrt).tocoo()\n    return normalized_laplacian\n\ndef calculate_scaled_laplacian(adj_mx, lambda_max=2, undirected=True):\n    if undirected:\n        adj_mx = np.maximum.reduce([adj_mx, adj_mx.T])\n    L = calculate_normalized_laplacian(adj_mx)\n    if lambda_max is None:\n        lambda_max, _ = linalg.eigsh(L, 1, which='LM')\n        lambda_max = lambda_max[0]\n    L = sp.csr_matrix(L)\n    M, _ = L.shape\n    I = sp.identity(M, format='csr', dtype=L.dtype)\n    L = (2 / lambda_max * L) - I\n    return L.astype(np.float32).todense()\n\n\ndef load_pickle(pickle_file):\n    try:\n        with open(pickle_file, 'rb') as f:\n            pickle_data = pickle.load(f)\n    except UnicodeDecodeError as e:\n        with open(pickle_file, 'rb') as f:\n            pickle_data = pickle.load(f, encoding='latin1')\n    except Exception as e:\n        print('Unable to load data ', pickle_file, ':', e)\n        raise\n    return pickle_data\n\ndef load_adj(pkl_filename):\n    sensor_ids, sensor_id_to_ind, adj = load_pickle(pkl_filename)\n    return adj\n\nclass Optim(object):\n\n    def _makeOptimizer(self):\n        if self.method == 'sgd':\n            self.optimizer = optim.SGD(self.params, lr=self.lr, weight_decay=self.lr_decay)\n        elif self.method == 'adagrad':\n            self.optimizer = optim.Adagrad(self.params, lr=self.lr, weight_decay=self.lr_decay)\n        elif self.method == 'adadelta':\n            self.optimizer = optim.Adadelta(self.params, lr=self.lr, weight_decay=self.lr_decay)\n        elif self.method == 'adam':\n            self.optimizer = optim.Adam(self.params, lr=self.lr, weight_decay=self.lr_decay)\n        else:\n            raise RuntimeError(\"Invalid optim method: \" + self.method)\n\n    def __init__(self, params, method, lr, clip, lr_decay=1, start_decay_at=None):\n        self.params = params  # careful: params may be a generator\n        self.last_ppl = None\n        self.lr = lr\n        self.clip = clip\n        self.method = method\n        self.lr_decay = lr_decay\n        self.start_decay_at = start_decay_at\n        self.start_decay = False\n\n        self._makeOptimizer()\n\n    def step(self):\n        # Compute gradients norm.\n        grad_norm = 0\n        if self.clip is not None:\n            torch.nn.utils.clip_grad_norm_(self.params, self.clip)\n\n        # for param in self.params:\n        #     grad_norm += math.pow(param.grad.data.norm(), 2)\n        #\n        # grad_norm = math.sqrt(grad_norm)\n        # if grad_norm > 0:\n        #     shrinkage = self.max_grad_norm / grad_norm\n        # else:\n        #     shrinkage = 1.\n        #\n        # for param in self.params:\n        #     if shrinkage < 1:\n        #         param.grad.data.mul_(shrinkage)\n        self.optimizer.step()\n        return  grad_norm\n\n    # decay learning rate if val perf does not improve or we hit the start_decay_at limit\n    def updateLearningRate(self, ppl, epoch):\n        if self.start_decay_at is not None and epoch >= self.start_decay_at:\n            self.start_decay = True\n        if self.last_ppl is not None and ppl > self.last_ppl:\n            self.start_decay = True\n\n        if self.start_decay:\n            self.lr = self.lr * self.lr_decay\n            print(\"Decaying learning rate to %g\" % self.lr)\n        #only decay for one epoch\n        self.start_decay = False\n\n        self.last_ppl = ppl\n\n        self._makeOptimizer()\n\n# def load_dataset(dataset_dir, batch_size, valid_batch_size= None, test_batch_size=None):\n#     data = {}\n#     for category in ['train', 'val', 'test']:\n#         cat_data = np.load(os.path.join(dataset_dir, category + '.npz'))\n#         data['x_' + category] = cat_data['x']\n#         data['y_' + category] = cat_data['y']\n#     scaler = StandardScaler(mean=data['x_train'][..., 0].mean(), std=data['x_train'][..., 0].std())\n#     # Data format\n#     for category in ['train', 'val', 'test']:\n#         data['x_' + category][..., 0] = scaler.transform(data['x_' + category][..., 0])\n\n#     data['train_loader'] = DataLoaderM(data['x_train'], data['y_train'], batch_size)\n#     data['val_loader'] = DataLoaderM(data['x_val'], data['y_val'], valid_batch_size)\n#     data['test_loader'] = DataLoaderM(data['x_test'], data['y_test'], test_batch_size)\n#     data['scaler'] = scaler\n#     return data\n\n\n\ndef masked_mse(preds, labels, null_val=np.nan):\n    if np.isnan(null_val):\n        mask = ~torch.isnan(labels)\n    else:\n        mask = (labels!=null_val)\n    mask = mask.float()\n    mask /= torch.mean((mask))\n    mask = torch.where(torch.isnan(mask), torch.zeros_like(mask), mask)\n    loss = (preds-labels)**2\n    loss = loss * mask\n    loss = torch.where(torch.isnan(loss), torch.zeros_like(loss), loss)\n    return torch.mean(loss)\n\ndef masked_rmse(preds, labels, null_val=np.nan):\n    return torch.sqrt(masked_mse(preds=preds, labels=labels, null_val=null_val))\n\n\ndef masked_mae(preds, labels, null_val=np.nan):\n    if np.isnan(null_val):\n        mask = ~torch.isnan(labels)\n    else:\n        mask = (labels!=null_val)\n    mask = mask.float()\n    mask /=  torch.mean((mask))\n    mask = torch.where(torch.isnan(mask), torch.zeros_like(mask), mask)\n    loss = torch.abs(preds-labels)\n    loss = loss * mask\n    loss = torch.where(torch.isnan(loss), torch.zeros_like(loss), loss)\n    return torch.mean(loss)\n\ndef masked_mape(preds, labels, null_val=np.nan):\n    if np.isnan(null_val):\n        mask = ~torch.isnan(labels)\n    else:\n        mask = (labels!=null_val)\n    mask = mask.float()\n    mask /=  torch.mean((mask))\n    mask = torch.where(torch.isnan(mask), torch.zeros_like(mask), mask)\n    loss = torch.abs(preds-labels)/labels\n    loss = loss * mask\n    loss = torch.where(torch.isnan(loss), torch.zeros_like(loss), loss)\n    return torch.mean(loss)\n\n\ndef metric(pred, real):\n    mae = masked_mae(pred,real,0.0).item()\n    mape = masked_mape(pred,real,0.0).item()\n    rmse = masked_rmse(pred,real,0.0).item()\n    return mae,mape,rmse\n\n\ndef load_node_feature(path):\n    fi = open(path)\n    x = []\n    for li in fi:\n        li = li.strip()\n        li = li.split(\",\")\n        e = [float(t) for t in li[1:]]\n        x.append(e)\n    x = np.array(x)\n    mean = np.mean(x,axis=0)\n    std = np.std(x,axis=0)\n    z = torch.tensor((x-mean)/std,dtype=torch.float)\n    return z\n\n\ndef normal_std(x):\n    return x.std() * np.sqrt((len(x) - 1.) / (len(x)))\n\n\n\ndef load_dataset(uctb_data_loader, batch_size, valid_batch_size=None, test_batch_size=None):\n    # x_train (num_slots, time_steps, num_stations, input_dims)\n    # y_train (num_slots, time_steps, num_stations, input_dims)\n    data = {}\n\n    # split data\n    train_closeness, val_closeness = SplitData.split_data(uctb_data_loader.train_closeness, [0.9, 0.1])\n    train_period, val_period = SplitData.split_data(uctb_data_loader.train_period, [0.9, 0.1])\n    train_trend, val_trend = SplitData.split_data(uctb_data_loader.train_trend, [0.9, 0.1])\n    train_y, val_y = SplitData.split_data(uctb_data_loader.train_y, [0.9, 0.1])\n    # pdb.set_trace()\n    # train_x = np.concatenate([train_trend, train_period, train_closeness],axis=2).transpose( # [0,3,1,2] [0,2,1,3]\n    if uctb_data_loader.period_len > 0 and uctb_data_loader.trend_len > 0:\n        data[\"x_train\"] = np.concatenate([train_trend, train_period, train_closeness], axis=2).transpose([0, 2, 1, 3])\n        data[\"x_val\"] = np.concatenate([val_trend, val_period, val_closeness], axis=2).transpose([0, 2, 1, 3])\n        data[\"x_test\"] = np.concatenate(\n            [uctb_data_loader.test_trend, uctb_data_loader.test_period, uctb_data_loader.test_closeness],\n            axis=2).transpose([0, 2, 1, 3])\n    else:\n        data[\"x_train\"] = train_closeness.transpose([0, 2, 1, 3])\n        data[\"x_val\"] = val_closeness.transpose([0, 2, 1, 3])\n        data[\"x_test\"] = uctb_data_loader.test_closeness.transpose([0, 2, 1, 3])\n\n    data[\"y_train\"] = train_y[:, np.newaxis]\n    data[\"y_val\"] = val_y[:, np.newaxis]\n    data[\"y_test\"] = uctb_data_loader.test_y[:, np.newaxis]\n\n    print(\"x_train\", data[\"x_train\"].shape)\n    print(\"y_train\", data[\"y_train\"].shape)\n    print(\"x_val\", data[\"x_val\"].shape)\n    print(\"y_val\", data[\"y_val\"].shape)\n    print(\"x_test\", data[\"x_test\"].shape)\n    print(\"y_test\", data[\"y_test\"].shape)\n\n\n\n    data['train_loader'] = DataLoaderM(data['x_train'], data['y_train'], batch_size)\n    data['val_loader'] = DataLoaderM(data['x_val'], data['y_val'], valid_batch_size)\n    data['test_loader'] = DataLoaderM(data['x_test'], data['y_test'], test_batch_size)\n    return data"
  },
  {
    "path": "UCTB/utils/utils_STGCN.py",
    "content": "from os.path import join as pjoin\nimport tensorflow as tf\nimport numpy as np\nimport time\nfrom UCTB.preprocess import SplitData\nfrom UCTB.model.STGCN import build_model, gen_batch\n\n\ndef model_save(sess, global_steps, model_name, save_path='./output/models/'):\n    '''\n    Save the checkpoint of trained model.\n    :param sess: tf.Session().\n    :param global_steps: tensor, record the global step of training in epochs.\n    :param model_name: str, the name of saved model.\n    :param save_path: str, the path of saved model.\n    :return:\n    '''\n    saver = tf.train.Saver(max_to_keep=3)\n    prefix_path = saver.save(sess, pjoin(\n        save_path, model_name), global_step=global_steps)\n    print(f'<< Saving model to {prefix_path} ...')\n\n\ndef model_train(inputs, blocks, args, sum_path='./output/models'):\n    '''\n    Train the base model.\n    :param inputs: instance of class Dataset, data source for training.\n    :param blocks: list, channel configs of st_conv blocks.\n    :param args: instance of class argparse, args for training.\n    '''\n    n, n_his, n_pred = args.n_route, args.n_his, args.n_pred\n    print(n_his)\n    Ks, Kt = args.ks, args.kt\n    batch_size, epoch, inf_mode, opt = args.batch_size, args.epoch, args.inf_mode, args.opt\n\n    # Placeholder for model training\n    x = tf.placeholder(tf.float32, [None, n_his + 1, n, 1], name='data_input')\n    keep_prob = tf.placeholder(tf.float32, name='keep_prob')\n\n    # Define model loss\n    train_loss, pred = build_model(x, n_his, Ks, Kt, blocks, keep_prob)\n    tf.summary.scalar('train_loss', train_loss)\n    copy_loss = tf.add_n(tf.get_collection('copy_loss'))\n    tf.summary.scalar('copy_loss', copy_loss)\n\n    # Learning rate settings\n    global_steps = tf.Variable(0, trainable=False)\n    len_train = inputs.get_len('train')\n    if len_train % batch_size == 0:\n        epoch_step = len_train / batch_size\n    else:\n        epoch_step = int(len_train / batch_size) + 1\n    # Learning rate decay with rate 0.7 every 5 epochs.\n    lr = tf.train.exponential_decay(\n        args.lr, global_steps, decay_steps=5 * epoch_step, decay_rate=0.7, staircase=True)\n    tf.summary.scalar('learning_rate', lr)\n    step_op = tf.assign_add(global_steps, 1)\n    with tf.control_dependencies([step_op]):\n        if opt == 'RMSProp':\n            train_op = tf.train.RMSPropOptimizer(lr).minimize(train_loss)\n        elif opt == 'ADAM':\n            train_op = tf.train.AdamOptimizer(lr).minimize(train_loss)\n        else:\n            raise ValueError(f'ERROR: optimizer \"{opt}\" is not defined.')\n\n    merged = tf.summary.merge_all()\n\n    with tf.Session() as sess:\n        writer = tf.summary.FileWriter(pjoin(sum_path, 'train'), sess.graph)\n        sess.run(tf.global_variables_initializer())\n\n        if inf_mode == 'sep':\n            # for inference mode 'sep', the type of step index is int.\n            step_idx = n_pred - 1\n            tmp_idx = [step_idx]\n            min_val = min_va_val = np.array([4e1, 1e5, 1e5])\n        elif inf_mode == 'merge':\n            # for inference mode 'merge', the type of step index is np.ndarray.\n            step_idx = tmp_idx = np.arange(3, n_pred + 1, 3) - 1\n            min_val = min_va_val = np.array([4e1, 1e5, 1e5] * len(step_idx))\n        else:\n            raise ValueError(f'ERROR: test mode \"{inf_mode}\" is not defined.')\n\n        for i in range(epoch):\n            start_time = time.time()\n            for j, x_batch in enumerate(\n                    gen_batch(inputs.get_data('train'), batch_size, dynamic_batch=True, shuffle=True)):\n                summary, _ = sess.run([merged, train_op], feed_dict={\n                                      x: x_batch[:, 0:n_his + 1, :, :], keep_prob: 1.0})\n                writer.add_summary(summary, i * epoch_step + j)\n                if j % 50 == 0:\n                    loss_value = \\\n                        sess.run([train_loss, copy_loss],\n                                 feed_dict={x: x_batch[:, 0:n_his + 1, :, :], keep_prob: 1.0})\n                    print(\n                        f'Epoch {i:2d}, Step {j:3d}: [{loss_value[0]:.3f}, {loss_value[1]:.3f}]')\n            print(\n                f'Epoch {i:2d} Training Time {time.time() - start_time:.3f}s')\n            if (i + 1) % args.save == 0:\n                model_save(sess, global_steps, 'STGCN', save_path=sum_path)\n        writer.close()\n    print('Training model finished!')\n\n\ndef model_test(inputs, batch_size, n_his, n_pred, inf_mode, load_path='./output/models/'):\n    '''\n    Load and test saved model from the checkpoint.\n    :param inputs: instance of class Dataset, data source for test.\n    :param batch_size: int, the size of batch.\n    :param n_his: int, the length of historical records for training.\n    :param n_pred: int, the length of prediction.\n    :param inf_mode: str, test mode - 'merge / multi-step test' or 'separate / single-step test'.\n    :param load_path: str, the path of loaded model.\n    '''\n    model_path = tf.train.get_checkpoint_state(load_path).model_checkpoint_path\n\n    test_graph = tf.Graph()\n\n    with test_graph.as_default():\n        saver = tf.train.import_meta_graph(pjoin(f'{model_path}.meta'))\n\n    with tf.Session(graph=test_graph) as test_sess:\n        saver.restore(test_sess, tf.train.latest_checkpoint(load_path))\n        print(f'>> Loading saved model from {model_path} ...')\n\n        pred = test_graph.get_collection('y_pred')\n\n        if inf_mode == 'sep':\n            # for inference mode 'sep', the type of step index is int.\n            step_idx = n_pred - 1\n            tmp_idx = [step_idx]\n        elif inf_mode == 'merge':\n            # for inference mode 'merge', the type of step index is np.ndarray.\n            step_idx = tmp_idx = np.arange(3, n_pred + 1, 3) - 1\n        else:\n            raise ValueError(f'ERROR: test mode \"{inf_mode}\" is not defined.')\n\n        x_test = inputs.get_data('test')\n\n        y_test, len_test = multi_pred(\n            test_sess, pred, x_test, batch_size, n_his, n_pred, step_idx)\n\n    return y_test\n\n\ndef data_gen(data_loader):\n    '''\n    Source file load and dataset generation.\n    :param file_path: str, the file path of data source.\n    :param data_config: tuple, the configs of dataset in train, validation, test.\n    :param n_route: int, the number of routes in the graph.\n    :param n_frame: int, the number of frame within a standard sequence unit,\n                         which contains n_his = 12 and n_pred = 9 (3 /15 min, 6 /30 min & 9 /45 min).\n    :param day_slot: int, the number of time slots per day, controlled by the time window (5 min as default).\n    :return: dict, dataset that contains training, validation and test with stats.\n    '''\n\n    # split data\n    train_closeness, val_closeness = SplitData.split_data(\n        data_loader.train_closeness, [0.9, 0.1])\n    train_period, val_period = SplitData.split_data(\n        data_loader.train_period, [0.9, 0.1])\n    train_trend, val_trend = SplitData.split_data(\n        data_loader.train_trend, [0.9, 0.1])\n    train_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\n    test_y = data_loader.test_y[...,np.newaxis]\n    train_y = train_y[...,np.newaxis]\n    val_y = val_y[...,np.newaxis]\n    # T, num_node, dimension, 1 -> T, dimension, num_node, 1\n    seq_train = np.concatenate(\n            [train_trend, train_period, train_closeness, train_y], axis=2).transpose([0, 2, 1, 3])\n    seq_val = np.concatenate(\n            [val_trend, val_period, val_closeness, val_y], axis=2).transpose([0, 2, 1, 3])\n    seq_test = np.concatenate([data_loader.test_trend, data_loader.test_period, data_loader.test_closeness, test_y],\n                                  axis=2).transpose([0, 2, 1, 3])\n\n    # x_train, x_val, x_test: np.array, [sample_size, n_frame, n_route, channel_size].\n    x_train = seq_train\n    x_val =seq_val\n    x_test = seq_test\n\n    x_data = {'train': x_train, 'val': x_val, 'test': x_test}\n    dataset = Dataset(x_data)\n    return dataset\n\n\ndef multi_pred(sess, y_pred, seq, batch_size, n_his, n_pred, step_idx, dynamic_batch=True):\n    '''\n    Multi_prediction function.\n    :param sess: tf.Session().\n    :param y_pred: placeholder.\n    :param seq: np.ndarray, [len_seq, n_frame, n_route, C_0].\n    :param batch_size: int, the size of batch.\n    :param n_his: int, size of historical records for training.\n    :param n_pred: int, the length of prediction.\n    :param step_idx: int or list, index for prediction slice.\n    :param dynamic_batch: bool, whether changes the batch size in the last one if its length is less than the default.\n    :return y_ : tensor, 'sep' [len_inputs, n_route, 1]; 'merge' [step_idx, len_inputs, n_route, 1].\n            len_ : int, the length of prediction.\n    '''\n    pred_list = []\n    for i in gen_batch(seq, min(batch_size, len(seq)), dynamic_batch=dynamic_batch):\n        # Note: use np.copy() to avoid the modification of source data.\n        test_seq = np.copy(i[:, 0:n_his + 1, :, :])\n        step_list = []\n        for j in range(n_pred):\n            pred = sess.run(y_pred,\n                            feed_dict={'data_input:0': test_seq, 'keep_prob:0': 1.0})\n            if isinstance(pred, list):\n                pred = np.array(pred[0])\n            test_seq[:, 0:n_his - 1, :, :] = test_seq[:, 1:n_his, :, :]\n            test_seq[:, n_his - 1, :, :] = pred\n            step_list.append(pred)\n        pred_list.append(step_list)\n    #  pred_array -> [n_pred, batch_size, n_route, C_0)\n    pred_array = np.concatenate(pred_list, axis=1)\n    return pred_array[step_idx], pred_array.shape[1]\n\n\nclass Dataset(object):\n    def __init__(self, data):\n        self.__data = data\n\n\n    def get_data(self, type):\n        return self.__data[type]\n\n\n\n    def get_len(self, type):\n        return len(self.__data[type])\n"
  },
  {
    "path": "UCTB/utils/utils_STSGCN.py",
    "content": "import time\nimport numpy as np\nimport mxnet as mx\nfrom UCTB.train.LossFunction import masked_mse_np\nfrom UCTB.evaluation.metric import rmse, mape\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\nfrom UCTB.preprocess import SplitData\nfrom UCTB.model.STSGCN import construct_model\n\n\ndef configData(args, data_loader, batch_size, config, ctx):\n    print(\"args['normalize']\", args.normalize)\n    normalizer = data_loader.normalizer\n    graph_obj = GraphGenerator(graph='distance', data_loader=data_loader)\n\n    config[\"num_of_vertices\"] = data_loader.station_number\n    config[\"points_per_hour\"] = data_loader.closeness_len + data_loader.period_len + data_loader.trend_len\n    num_of_vertices = config[\"num_of_vertices\"]\n    net = construct_model(config, AM=graph_obj.AM[0])\n\n    model_name = \"{}_{}_{}\".format(args.dataset, args.city, args.MergeIndex)\n    print(\"model_name:\", model_name)\n\n    train_closeness, val_closeness = SplitData.split_data(data_loader.train_closeness, [0.9, 0.1])\n    train_period, val_period = SplitData.split_data(data_loader.train_period, [0.9, 0.1])\n    train_trend, val_trend = SplitData.split_data(data_loader.train_trend, [0.9, 0.1])\n    train_y, val_y = SplitData.split_data(data_loader.train_y, [0.9, 0.1])\n\n    # T, num_node, 1 -> T, 1, num_node\n    train_y = train_y.transpose([0, 2, 1])\n    val_y = val_y.transpose([0, 2, 1])\n    test_y = data_loader.test_y.transpose([0, 2, 1])\n\n    # T, num_node, dimension, 1 -> T, dimension, num_node, 1\n\n    seq_train = np.concatenate([train_trend, train_period, train_closeness], axis=2).transpose([0, 2, 1, 3])\n    seq_val = np.concatenate([val_trend, val_period, val_closeness], axis=2).transpose([0, 2, 1, 3])\n    seq_test = np.concatenate([data_loader.test_trend, data_loader.test_period, data_loader.test_closeness],\n                                  axis=2).transpose([0, 2, 1, 3])\n\n\n    print(seq_train.shape, seq_val.shape, seq_test.shape)\n\n    loaders = []\n    true_values = []\n    for item in [\"train\", \"val\", \"test\"]:\n        loaders.append(\n            mx.io.NDArrayIter(\n                eval(\"seq_{}\".format(item)), eval(\"{}_y\".format(item)),\n                batch_size=batch_size,\n                shuffle=True,\n                label_name='label'\n            )\n        )\n        true_values.append(eval(\"{}_y\".format(item)))\n\n    train_loader, val_loader, test_loader = loaders\n    _, val_y, test_y = true_values\n\n    global_epoch = 1\n    training_samples = len(seq_train)\n    global_train_steps = training_samples // batch_size + 1\n    all_info = []\n    epochs = config['epochs']\n\n    mod = mx.mod.Module(\n        net,\n        data_names=['data'],\n        label_names=['label'],\n        context=ctx\n    )\n\n    mod.bind(\n        data_shapes=[(\n            'data',\n            (batch_size, config['points_per_hour'], num_of_vertices, 1)\n        ), ],\n        label_shapes=[(\n            'label',\n            (batch_size, config['num_for_predict'], num_of_vertices)\n        )]\n    )\n\n    mod.init_params(initializer=mx.init.Xavier(magnitude=0.0003))\n    lr_sch = mx.lr_scheduler.PolyScheduler(\n        max_update=global_train_steps * epochs * config['max_update_factor'],\n        base_lr=config['learning_rate'],\n        pwr=2,\n        warmup_steps=global_train_steps\n    )\n\n    mod.init_optimizer(\n        optimizer=config['optimizer'],\n        optimizer_params=(('lr_scheduler', lr_sch),)\n    )\n\n    num_of_parameters = 0\n    for param_name, param_value in mod.get_params()[0].items():\n        # print(param_name, param_value.shape)\n        num_of_parameters += np.prod(param_value.shape)\n    print(\"Number of Parameters: {}\".format(num_of_parameters), flush=True)\n\n    metric = mx.metric.create(['RMSE', 'MAE'], output_names=['pred_output'])\n\n    if args.plot:\n        graph = mx.viz.plot_network(net)\n        graph.format = 'png'\n        graph.render('graph')\n    return model_name, epochs, metric, mod, train_loader, val_loader, test_loader, normalizer, val_y, test_y, all_info\n\n\ndef training(epochs, metric, mod, train_loader, val_loader, test_loader, normalizer, val_y, test_y, all_info):\n    global global_epoch\n    global_epoch = 1\n    lowest_val_loss = np.inf\n    for _ in range(epochs):\n        t = time.time()\n        info = [global_epoch]\n        train_loader.reset()\n        metric.reset()\n        for idx, databatch in enumerate(train_loader):\n            # print(databatch,type(databatch))\n            mod.forward_backward(databatch)\n            mod.update_metric(metric, databatch.label)\n            mod.update()\n        metric_values = dict(zip(*metric.get()))\n\n        print('training: Epoch: %s, RMSE: %.2f, MAE: %.2f, time: %.2f s' % (\n            global_epoch, metric_values['rmse'], metric_values['mae'],\n            time.time() - t), flush=True)\n        # info.append(metric_values['mae'])\n        info.append(metric_values['rmse'])\n\n        val_loader.reset()\n        prediction = mod.predict(val_loader)[1].asnumpy()\n        # loss = masked_mae_np(val_y, prediction, 0)\n        loss = masked_mse_np(val_y, prediction, 0)\n        print('validation: Epoch: %s, loss: %.2f, time: %.2f s' % (\n            global_epoch, loss, time.time() - t), flush=True)\n        info.append(loss)\n\n        if loss < lowest_val_loss:\n\n            test_loader.reset()\n            prediction = mod.predict(test_loader)[1].asnumpy()\n\n            prediction = normalizer.inverse_transform(prediction)\n            de_norm_test_y = normalizer.inverse_transform(test_y)\n            rmse_result = rmse(prediction=prediction.squeeze(), target=de_norm_test_y.squeeze())\n            mape_result = mape(prediction=prediction.squeeze(), target=de_norm_test_y.squeeze(), threshold=0.01)\n\n            print('test: Epoch: {}, MAPE: {:.2f}, RMSE: {:.2f}, '\n                  'time: {:.2f}s'.format(\n                global_epoch, mape_result, rmse_result, time.time() - t))\n            print(flush=True)\n            info.extend((mape_result, rmse_result))\n            all_info.append(info)\n            lowest_val_loss = loss\n\n        global_epoch += 1\n\n\n\n"
  },
  {
    "path": "__init__.py",
    "content": ""
  },
  {
    "path": "build.py",
    "content": "import os\n\nos.system(\"python setup.py sdist bdist_wheel\")"
  },
  {
    "path": "build_install.py",
    "content": "import os\n\nos.system(\"python setup.py sdist bdist_wheel\")\nos.system(\"pip install -U dist/UCTB-0.3.5-py3-none-any.whl\")"
  },
  {
    "path": "docs/.buildinfo",
    "content": "# Sphinx build info version 1\n# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.\nconfig: 3f9422ea59d6af9d5ca292dc751485b5\ntags: 645f666f9bcd5a90fca523b33c5a78b7\n"
  },
  {
    "path": "docs/.nojekyll",
    "content": ""
  },
  {
    "path": "docs/APIReference.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6. API Reference &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"next\" title=\"6.1. UCTB.dataset package\" href=\"UCTB.dataset.html\"/>\n        <link rel=\"prev\" title=\"5. Visualization-tool\" href=\"md_file/visualization_tool.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">6. API Reference</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html\">6.1. UCTB.dataset package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html\">6.2. UCTB.preprocess package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html\">6.3. UCTB.model_unit package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html\">6.4. UCTB.model package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.evaluation.html\">6.5. UCTB.evaluation package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html\">6.6. UCTB.train package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.utils.html\">6.7. UCTB.utils package</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>6. API Reference</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/APIReference.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"api-reference\">\n<h1>6. API Reference<a class=\"headerlink\" href=\"#api-reference\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.dataset.html\">6.1. UCTB.dataset package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.data_loader\">6.1.1. UCTB.dataset.data_loader module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.dataset\">6.1.2. UCTB.dataset.dataset module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.preprocess.html\">6.2. UCTB.preprocess package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#uctb-preprocess-graphgenerator-module\">6.2.1. UCTB.preprocess.GraphGenerator module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.preprocessor\">6.2.2. UCTB.preprocess.preprocessor module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.time_utils\">6.2.3. UCTB.preprocess.time_utils module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.model_unit.html\">6.3. UCTB.model_unit package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.BaseModel\">6.3.1. UCTB.model_unit.BaseModel module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.DCRNN_CELL\">6.3.2. UCTB.model_unit.DCRNN_CELL module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.GraphModelLayers\">6.3.3. UCTB.model_unit.GraphModelLayers module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.ST_RNN\">6.3.4. UCTB.model_unit.ST_RNN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.model.html\">6.4. UCTB.model package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ARIMA\">6.4.1. UCTB.model.ARIMA module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DCRNN\">6.4.2. UCTB.model.DCRNN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DeepST\">6.4.3. UCTB.model.DeepST module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GeoMAN\">6.4.4. UCTB.model.GeoMAN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.HM\">6.4.5. UCTB.model.HM module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STMeta\">6.4.6. UCTB.model.STMeta module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_MGCN\">6.4.7. UCTB.model.ST_MGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_ResNet\">6.4.8. UCTB.model.ST_ResNet module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.XGBoost\">6.4.9. UCTB.model.XGBoost module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.AGCRN\">6.4.10. UCTB.model.AGCRN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ASTGCN\">6.4.11. UCTB.model.ASTGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GMAN\">6.4.12. UCTB.model.GMAN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#uctb-model-graphwavenet-module\">6.4.13. UCTB.model.GraphWaveNet module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STGCN\">6.4.14. UCTB.model.STGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STSGCN\">6.4.15. UCTB.model.STSGCN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.evaluation.html\">6.5. UCTB.evaluation package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.evaluation.html#module-UCTB.evaluation.metric\">6.5.1. UCTB.evaluation.metric module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.train.html\">6.6. UCTB.train package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.EarlyStopping\">6.6.1. UCTB.train.EarlyStopping module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.MiniBatchTrain\">6.6.2. UCTB.train.MiniBatchTrain module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.utils.html\">6.7. UCTB.utils package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.utils.html#module-UCTB.utils.multi_threads\">6.7.1. UCTB.utils.multi_threads module</a></li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.dataset.html\" class=\"btn btn-neutral float-right\" title=\"6.1. UCTB.dataset package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"md_file/visualization_tool.html\" class=\"btn btn-neutral\" title=\"5. Visualization-tool\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/UCTB.dataset.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.1. UCTB.dataset package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.2. UCTB.preprocess package\" href=\"UCTB.preprocess.html\"/>\n        <link rel=\"prev\" title=\"6. API Reference\" href=\"APIReference.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.1. UCTB.dataset package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.dataset.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-dataset-package\">\n<h1>6.1. UCTB.dataset package<a class=\"headerlink\" href=\"#uctb-dataset-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.dataset.data_loader\">\n<span id=\"uctb-dataset-data-loader-module\"></span><h2>6.1.1. UCTB.dataset.data_loader module<a class=\"headerlink\" href=\"#module-UCTB.dataset.data_loader\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.dataset.data_loader.</code><code class=\"descname\">NodeTrafficLoader</code><span class=\"sig-paren\">(</span><em>dataset</em>, <em>city=None</em>, <em>data_range='all'</em>, <em>train_data_length='all'</em>, <em>test_ratio=0.1</em>, <em>closeness_len=6</em>, <em>period_len=7</em>, <em>trend_len=4</em>, <em>target_length=1</em>, <em>normalize=True</em>, <em>workday_parser=&lt;function is_work_day_america&gt;</em>, <em>with_tpe=False</em>, <em>data_dir=None</em>, <em>MergeIndex=1</em>, <em>MergeWay='sum'</em>, <em>remove=True</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>The data loader that extracts and processes data from a <code class=\"xref py py-obj docutils literal\"><span class=\"pre\">DataSet</span></code> object.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>dataset</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – A string containing path of the dataset pickle file or a string of name of the dataset.</li>\n<li><strong>city</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><code class=\"xref py py-obj docutils literal\"><span class=\"pre\">str</span></code></a> or <code class=\"docutils literal\"><span class=\"pre\">None</span></code>) – <code class=\"docutils literal\"><span class=\"pre\">None</span></code> if dataset is file path, or a string of name of the city.\nDefault: <code class=\"docutils literal\"><span class=\"pre\">None</span></code></li>\n<li><strong>data_range</strong> – The range of data extracted from <code class=\"docutils literal\"><span class=\"pre\">self.dataset</span></code> to be further used. If set to <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code>, all data in\n<code class=\"docutils literal\"><span class=\"pre\">self.dataset</span></code> will be used. If set to a float between 0.0 and 1.0, the relative former proportion of data in\n<code class=\"docutils literal\"><span class=\"pre\">self.dataset</span></code> will be used. If set to a list of two integers <code class=\"docutils literal\"><span class=\"pre\">[start,</span> <span class=\"pre\">end]</span></code>, the data from <em>start</em> day to\n(<em>end</em> - 1) day of data in <code class=\"docutils literal\"><span class=\"pre\">self.dataset</span></code> will be used. Default: <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code></li>\n<li><strong>train_data_length</strong> – The length of train data. If set to <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code>, all data in the split train set will be used.\nIf set to int, the latest <code class=\"docutils literal\"><span class=\"pre\">train_data_length</span></code> days of data will be used as train set. Default: <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code></li>\n<li><strong>test_ratio</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – The ratio of test set as data will be split into train set and test set. Default: 0.1</li>\n<li><strong>closeness_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of closeness data history. The former consecutive <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> time slots\nof data will be used as closeness history. Default: 6</li>\n<li><strong>period_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of period data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> days will be used as period history. Default: 7</li>\n<li><strong>trend_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of trend data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">trend_len</span></code> weeks (every seven days) will be used as trend history. Default: 4</li>\n<li><strong>target_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The numbers of steps that need prediction by one piece of history data. Have to be 1 now.\nDefault: 1</li>\n<li><strong>normalize</strong> (<em>bool|str|object</em>) – Select which normalizer to normalize input data. Default: <code class=\"docutils literal\"><span class=\"pre\">True</span></code></li>\n<li><strong>workday_parser</strong> – Used to build external features to be used in neural methods. Default: <code class=\"docutils literal\"><span class=\"pre\">is_work_day_america</span></code></li>\n<li><strong>with_tpe</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – If <code class=\"docutils literal\"><span class=\"pre\">True</span></code>, data loader will build time position embeddings. Default: <code class=\"docutils literal\"><span class=\"pre\">False</span></code></li>\n<li><strong>data_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><code class=\"xref py py-obj docutils literal\"><span class=\"pre\">str</span></code></a> or <code class=\"docutils literal\"><span class=\"pre\">None</span></code>) – The dataset directory. If set to <code class=\"docutils literal\"><span class=\"pre\">None</span></code>, a directory will be created. If\n<code class=\"docutils literal\"><span class=\"pre\">dataset</span></code> is file path, <code class=\"docutils literal\"><span class=\"pre\">data_dir</span></code> should be <code class=\"docutils literal\"><span class=\"pre\">None</span></code> too. Default: <code class=\"docutils literal\"><span class=\"pre\">None</span></code></li>\n<li><strong>MergeIndex</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The granularity of dataset will be <code class=\"docutils literal\"><span class=\"pre\">MergeIndex</span></code> * original granularity.</li>\n<li><strong>MergeWay</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – How to change the data granularity. Now it can be <code class=\"docutils literal\"><span class=\"pre\">sum</span></code> <code class=\"docutils literal\"><span class=\"pre\">average</span></code> or <code class=\"docutils literal\"><span class=\"pre\">max</span></code>.</li>\n<li><strong>remove</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – If <code class=\"docutils literal\"><span class=\"pre\">True</span></code>, dataloader  will remove stations whose average traffic is less than 1.\nOthewise, dataloader will use all stations.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.dataset\">\n<code class=\"descname\">dataset</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.dataset\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>DataSet</em> – The DataSet object storing basic data.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.daily_slots\">\n<code class=\"descname\">daily_slots</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.daily_slots\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The number of time slots in one single day.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.station_number\">\n<code class=\"descname\">station_number</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.station_number\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The number of nodes.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.external_dim\">\n<code class=\"descname\">external_dim</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.external_dim\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The number of dimensions of external features.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.train_closeness\">\n<code class=\"descname\">train_closeness</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.train_closeness\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>np.ndarray</em> – The closeness history of train set data. When <code class=\"docutils literal\"><span class=\"pre\">with_tpe</span></code> is <code class=\"docutils literal\"><span class=\"pre\">False</span></code>,\nits shape is [train_time_slot_num, <code class=\"docutils literal\"><span class=\"pre\">station_number</span></code>, <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code>, 1].\nOn the dimension of <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code>, data are arranged from earlier time slots to later time slots.\nIf <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> is set to 0, train_closeness will be an empty ndarray.\n<code class=\"docutils literal\"><span class=\"pre\">train_period</span></code>, <code class=\"docutils literal\"><span class=\"pre\">train_trend</span></code>, <code class=\"docutils literal\"><span class=\"pre\">test_closeness</span></code>, <code class=\"docutils literal\"><span class=\"pre\">test_period</span></code>, <code class=\"docutils literal\"><span class=\"pre\">test_trend</span></code> have similar shape\nand construction.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.train_y\">\n<code class=\"descname\">train_y</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.train_y\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>np.ndarray</em> – The train set data. Its shape is [train_time_slot_num, <code class=\"docutils literal\"><span class=\"pre\">station_number</span></code>, 1].\n<code class=\"docutils literal\"><span class=\"pre\">test_y</span></code> has similar shape and construction.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.make_concat\">\n<code class=\"descname\">make_concat</code><span class=\"sig-paren\">(</span><em>node='all'</em>, <em>is_train=True</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.make_concat\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>A function to concatenate all closeness, period and trend history data to use as inputs of models.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>node</strong> (int or <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code>) – To specify the index of certain node. If set to <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code>, return the concatenation\nresult of all nodes. If set to an integer, it will be the index of the selected node. Default: <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code></li>\n<li><strong>is_train</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – If set to <code class=\"docutils literal\"><span class=\"pre\">True</span></code>, <code class=\"docutils literal\"><span class=\"pre\">train_closeness</span></code>, <code class=\"docutils literal\"><span class=\"pre\">train_period</span></code>, and <code class=\"docutils literal\"><span class=\"pre\">train_trend</span></code> will be\nconcatenated. If set to <code class=\"docutils literal\"><span class=\"pre\">False</span></code>, <code class=\"docutils literal\"><span class=\"pre\">test_closeness</span></code>, <code class=\"docutils literal\"><span class=\"pre\">test_period</span></code>, and <code class=\"docutils literal\"><span class=\"pre\">test_trend</span></code> will be\nconcatenated. Default: True</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\">Function returns an ndarray with shape as\n[time_slot_num, <code class=\"docutils literal\"><span class=\"pre\">station_number</span></code>, <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> + <code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> + <code class=\"docutils literal\"><span class=\"pre\">trend_len</span></code>, 1],\nand time_slot_num is the temporal length of train set data if <code class=\"docutils literal\"><span class=\"pre\">is_train</span></code> is <code class=\"docutils literal\"><span class=\"pre\">True</span></code>\nor the temporal length of test set data if <code class=\"docutils literal\"><span class=\"pre\">is_train</span></code> is <code class=\"docutils literal\"><span class=\"pre\">False</span></code>.\nOn the second dimension, data are arranged as\n<code class=\"docutils literal\"><span class=\"pre\">earlier</span> <span class=\"pre\">closeness</span> <span class=\"pre\">-&gt;</span> <span class=\"pre\">later</span> <span class=\"pre\">closeness</span> <span class=\"pre\">-&gt;</span> <span class=\"pre\">earlier</span> <span class=\"pre\">period</span> <span class=\"pre\">-&gt;</span> <span class=\"pre\">later</span> <span class=\"pre\">period</span> <span class=\"pre\">-&gt;</span> <span class=\"pre\">earlier</span> <span class=\"pre\">trend</span> <span class=\"pre\">-&gt;</span> <span class=\"pre\">later</span> <span class=\"pre\">trend</span></code>.</p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">np.ndarray</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.dataset.dataset\">\n<span id=\"uctb-dataset-dataset-module\"></span><h2>6.1.2. UCTB.dataset.dataset module<a class=\"headerlink\" href=\"#module-UCTB.dataset.dataset\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.dataset.dataset.DataSet\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.dataset.dataset.</code><code class=\"descname\">DataSet</code><span class=\"sig-paren\">(</span><em>dataset</em>, <em>MergeIndex</em>, <em>MergeWay</em>, <em>city=None</em>, <em>data_dir=None</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>An object storing basic data from a formatted pickle file.\nSee also <a class=\"reference external\" href=\"./md_file/tutorial.html\">Build your own datasets</a>.\n:param dataset: A string containing path of the dataset pickle file or a string of name of the dataset.\n:type dataset: str\n:param city: <code class=\"docutils literal\"><span class=\"pre\">None</span></code> if dataset is file path, or a string of name of the city. Default: <code class=\"docutils literal\"><span class=\"pre\">None</span></code>\n:type city: str or <code class=\"docutils literal\"><span class=\"pre\">None</span></code>\n:param data_dir: The dataset directory. If set to <code class=\"docutils literal\"><span class=\"pre\">None</span></code>, a directory will be created.</p>\n<blockquote>\n<div>If <code class=\"docutils literal\"><span class=\"pre\">dataset</span></code> is file path, <code class=\"docutils literal\"><span class=\"pre\">data_dir</span></code> should be <code class=\"docutils literal\"><span class=\"pre\">None</span></code> too. Default: <code class=\"docutils literal\"><span class=\"pre\">None</span></code></div></blockquote>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n</tbody>\n</table>\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.data\">\n<code class=\"descname\">data</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.data\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>dict</em> – The data directly from the pickle file. <code class=\"docutils literal\"><span class=\"pre\">data</span></code> may have a <code class=\"docutils literal\"><span class=\"pre\">data['contribute_data']</span></code> dict to\nstore supplementary data.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.time_range\">\n<code class=\"descname\">time_range</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.time_range\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>list</em> – From <code class=\"docutils literal\"><span class=\"pre\">data['TimeRange']</span></code> in the format of [YYYY-MM-DD, YYYY-MM-DD] indicating the time\nrange of the data.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.time_fitness\">\n<code class=\"descname\">time_fitness</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.time_fitness\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – From <code class=\"docutils literal\"><span class=\"pre\">data['TimeFitness']</span></code> indicating how many minutes is a single time slot.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.node_traffic\">\n<code class=\"descname\">node_traffic</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.node_traffic\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>np.ndarray</em> – Data recording the main stream data of the nodes in during the time range.\nFrom <code class=\"docutils literal\"><span class=\"pre\">data['Node']['TrafficNode']</span></code> with shape as [time_slot_num, node_num].</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.node_monthly_interaction\">\n<code class=\"descname\">node_monthly_interaction</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.node_monthly_interaction\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>np.ndarray</em> – Data recording the monthly interaction of pairs of nodes.\nIts shape is [month_num, node_num, node_num].It’s from <code class=\"docutils literal\"><span class=\"pre\">data['Node']['TrafficMonthlyInteraction']</span></code>\nand is used to build interaction graph.\nIts an optional attribute and can be set as an empty list if interaction graph is not needed.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.node_station_info\">\n<code class=\"descname\">node_station_info</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.node_station_info\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>dict</em> – A dict storing the coordinates of nodes. It shall be formatted as {id (may be\narbitrary): [id (when sorted, should be consistant with index of <code class=\"docutils literal\"><span class=\"pre\">node_traffic</span></code>), latitude, longitude,\nother notes]}. It’s from <code class=\"docutils literal\"><span class=\"pre\">data['Node']['StationInfo']</span></code> and is used to build distance graph.\nIts an optional attribute and can be set as an empty list if distance graph is not needed.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.MergeIndex\">\n<code class=\"descname\">MergeIndex</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.MergeIndex\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – A int number that used to adjust the granularity of the dataset, the granularity of the new\ndataset is time_fitness*MergeIndex. default: 1</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.MergeWay\">\n<code class=\"descname\">MergeWay</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.MergeWay\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>str</em> – can be <cite>sum</cite> and <cite>average</cite>.  default: <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>sum</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.dataset.dataset.DataSet.merge_data\">\n<code class=\"descname\">merge_data</code><span class=\"sig-paren\">(</span><em>data</em>, <em>dataType</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.merge_data\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.preprocess.html\" class=\"btn btn-neutral float-right\" title=\"6.2. UCTB.preprocess package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"APIReference.html\" class=\"btn btn-neutral\" title=\"6. API Reference\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/UCTB.evaluation.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.5. UCTB.evaluation package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.6. UCTB.train package\" href=\"UCTB.train.html\"/>\n        <link rel=\"prev\" title=\"6.4. UCTB.model package\" href=\"UCTB.model.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.5. UCTB.evaluation package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.evaluation.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-evaluation-package\">\n<h1>6.5. UCTB.evaluation package<a class=\"headerlink\" href=\"#uctb-evaluation-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.evaluation.metric\">\n<span id=\"uctb-evaluation-metric-module\"></span><h2>6.5.1. UCTB.evaluation.metric module<a class=\"headerlink\" href=\"#module-UCTB.evaluation.metric\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.mae\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">mae</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=None</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.mae\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Mean Absolute Error (MAE)</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller or equal to threshold in target will be removed in computing the mae</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.mape\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">mape</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=0</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.mape\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Mean Absolute Percentage Error (MAPE)</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller than threshold in target will be removed in computing the mape.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.rmse\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">rmse</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=None</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.rmse\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Root Mean Square Error (RMSE)</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller or equal to threshold in target will be removed in computing the rmse</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.smape\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">smape</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=0</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.smape\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Symmetric Mean Absolute Percentage Error (SMAPE)</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller than threshold in target will be removed in computing the smape.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.trunc_mae\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">trunc_mae</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=0</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.trunc_mae\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><blockquote>\n<div>Mean Absolute Error with Truncation (Trunc_MAE)</div></blockquote>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller or equal to threshold in target will be replaced in computing the mae</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.trunc_rmse\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">trunc_rmse</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=0</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.trunc_rmse\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Root Mean Square Error with Truncation (trunc_RMSE)\n:param prediction: prediction with shape [batch_size, …]\n:type prediction: ndarray\n:param target: same shape with prediction, [batch_size, …]\n:type target: ndarray\n:param threshold: data smaller or equal to threshold in target</p>\n<blockquote>\n<div>will be replaced by threshold in computing the s_rmse</div></blockquote>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.trunc_smape\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">trunc_smape</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=0</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.trunc_smape\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Symmetric Mean Absolute Percentage Error with Truncation (Trunc_SMAPE)</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller than threshold in target will be replaced in computing the trunc_smape.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.train.html\" class=\"btn btn-neutral float-right\" title=\"6.6. UCTB.train package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.model.html\" class=\"btn btn-neutral\" title=\"6.4. UCTB.model package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/UCTB.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>UCTB package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>UCTB package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-package\">\n<h1>UCTB package<a class=\"headerlink\" href=\"#uctb-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"subpackages\">\n<h2>Subpackages<a class=\"headerlink\" href=\"#subpackages\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.dataset.html\">6.1. UCTB.dataset package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.data_loader\">6.1.1. UCTB.dataset.data_loader module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.dataset\">6.1.2. UCTB.dataset.dataset module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.evaluation.html\">6.5. UCTB.evaluation package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.evaluation.html#module-UCTB.evaluation.metric\">6.5.1. UCTB.evaluation.metric module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.model.html\">6.4. UCTB.model package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ARIMA\">6.4.1. UCTB.model.ARIMA module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DCRNN\">6.4.2. UCTB.model.DCRNN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DeepST\">6.4.3. UCTB.model.DeepST module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GeoMAN\">6.4.4. UCTB.model.GeoMAN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.HM\">6.4.5. UCTB.model.HM module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STMeta\">6.4.6. UCTB.model.STMeta module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_MGCN\">6.4.7. UCTB.model.ST_MGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_ResNet\">6.4.8. UCTB.model.ST_ResNet module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.XGBoost\">6.4.9. UCTB.model.XGBoost module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.AGCRN\">6.4.10. UCTB.model.AGCRN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ASTGCN\">6.4.11. UCTB.model.ASTGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GMAN\">6.4.12. UCTB.model.GMAN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#uctb-model-graphwavenet-module\">6.4.13. UCTB.model.GraphWaveNet module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STGCN\">6.4.14. UCTB.model.STGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STSGCN\">6.4.15. UCTB.model.STSGCN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.model_unit.html\">6.3. UCTB.model_unit package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.BaseModel\">6.3.1. UCTB.model_unit.BaseModel module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.DCRNN_CELL\">6.3.2. UCTB.model_unit.DCRNN_CELL module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.GraphModelLayers\">6.3.3. UCTB.model_unit.GraphModelLayers module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.ST_RNN\">6.3.4. UCTB.model_unit.ST_RNN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.preprocess.html\">6.2. UCTB.preprocess package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#uctb-preprocess-graphgenerator-module\">6.2.1. UCTB.preprocess.GraphGenerator module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.preprocessor\">6.2.2. UCTB.preprocess.preprocessor module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.time_utils\">6.2.3. UCTB.preprocess.time_utils module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.train.html\">6.6. UCTB.train package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.EarlyStopping\">6.6.1. UCTB.train.EarlyStopping module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.MiniBatchTrain\">6.6.2. UCTB.train.MiniBatchTrain module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.utils.html\">6.7. UCTB.utils package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.utils.html#module-UCTB.utils.multi_threads\">6.7.1. UCTB.utils.multi_threads module</a></li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<div class=\"section\" id=\"module-UCTB\">\n<span id=\"module-contents\"></span><h2>Module contents<a class=\"headerlink\" href=\"#module-UCTB\" title=\"Permalink to this headline\">¶</a></h2>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/UCTB.model.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.4. UCTB.model package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.5. UCTB.evaluation package\" href=\"UCTB.evaluation.html\"/>\n        <link rel=\"prev\" title=\"6.3. UCTB.model_unit package\" href=\"UCTB.model_unit.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.4. UCTB.model package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.model.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-model-package\">\n<h1>6.4. UCTB.model package<a class=\"headerlink\" href=\"#uctb-model-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.model.ARIMA\">\n<span id=\"uctb-model-arima-module\"></span><h2>6.4.1. UCTB.model.ARIMA module<a class=\"headerlink\" href=\"#module-UCTB.model.ARIMA\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.ARIMA.ARIMA\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ARIMA.</code><code class=\"descname\">ARIMA</code><span class=\"sig-paren\">(</span><em>time_sequence</em>, <em>order=None</em>, <em>seasonal_order=(0</em>, <em>0</em>, <em>0</em>, <em>0)</em>, <em>max_ar=6</em>, <em>max_ma=4</em>, <em>max_d=2</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ARIMA.ARIMA\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>ARIMA is a generalization of an ARMA (Autoregressive Moving Average) model, used in predicting\nfuture points in time series analysis.</p>\n<p>Since there may be three kinds of series data as closeness, period and trend history, this class\ntrains three different ARIMA models for each node according  to the three kinds of history data,\nand returns average of the predicted values by the models in prediction.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>time_sequence</strong> (<em>array_like</em>) – The observation value of time_series.</li>\n<li><strong>order</strong> (<em>iterable</em>) – It stores the (p, d, q) orders of the model for the number of AR parameters\n, differences, MA parameters. If set to None, ARIMA class will calculate the orders for\neach series based on max_ar, max_ma and max_d. Default: None</li>\n<li><strong>seasonal_order</strong> (<em>iterable</em>) – It stores the (P,D,Q,s) order of the seasonal ARIMA model for the\nAR parameters, differences, MA parameters, and periodicity. <cite>s</cite> is an integer giving the\nperiodicity (number of periods in season).</li>\n<li><strong>max_ar</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Maximum number of AR lags to use. Default: 6</li>\n<li><strong>max_ma</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Maximum number of MA lags to use. Default: 4</li>\n<li><strong>max_d</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Maximum number of degrees of differencing. Default: 2</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"docutils\">\n<dt>Attribute:</dt>\n<dd>order(iterable): (p, d, q) orders for ARIMA model.\nseasonal_order(iterable): (P,D,Q,s) order for seasonal ARIMA model.\nmodel_res(): Fit method for likelihood based models.</dd>\n</dl>\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model.ARIMA.ARIMA.adf_test\">\n<em class=\"property\">static </em><code class=\"descname\">adf_test</code><span class=\"sig-paren\">(</span><em>time_series</em>, <em>max_lags=None</em>, <em>verbose=True</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ARIMA.ARIMA.adf_test\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Augmented Dickey–Fuller test. The Augmented Dickey-Fuller test can be used to test for\na unit root in a univariate process in the presence of serial correlation.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model.ARIMA.ARIMA.get_order\">\n<code class=\"descname\">get_order</code><span class=\"sig-paren\">(</span><em>series</em>, <em>order=None</em>, <em>max_ar=6</em>, <em>max_ma=2</em>, <em>max_d=2</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ARIMA.ARIMA.get_order\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>If order is None, it simply returns order, otherwise, it calculates the (p, d, q) orders\nfor the series data based on max_ar, max_ma and max_d.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model.ARIMA.ARIMA.predict\">\n<code class=\"descname\">predict</code><span class=\"sig-paren\">(</span><em>time_sequences</em>, <em>forecast_step=1</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ARIMA.ARIMA.predict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><dl class=\"docutils\">\n<dt>Argues:</dt>\n<dd>time_sequences: The input time_series features.\nforecast_step: The number of predicted future steps. Default: 1</dd>\n</dl>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">Prediction results with shape of (len(time_sequence)/forecast_step,forecast_step=,1).</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">np.ndarray</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.DCRNN\">\n<span id=\"uctb-model-dcrnn-module\"></span><h2>6.4.2. UCTB.model.DCRNN module<a class=\"headerlink\" href=\"#module-UCTB.model.DCRNN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.DCRNN.DCRNN\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.DCRNN.</code><code class=\"descname\">DCRNN</code><span class=\"sig-paren\">(</span><em>num_node</em>, <em>num_diffusion_matrix</em>, <em>num_rnn_units=64</em>, <em>num_rnn_layers=1</em>, <em>max_diffusion_step=2</em>, <em>seq_len=6</em>, <em>use_curriculum_learning=False</em>, <em>input_dim=1</em>, <em>output_dim=1</em>, <em>cl_decay_steps=1000</em>, <em>target_len=1</em>, <em>lr=0.0001</em>, <em>epsilon=0.001</em>, <em>optimizer_name='Adam'</em>, <em>code_version='DCRNN-QuickStart'</em>, <em>model_dir='model_dir'</em>, <em>gpu_device='0'</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.DCRNN.DCRNN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://arxiv.org/pdf/1707.01926.pdf\">Diffusion convolutional recurrent neural network: Data-driven traffic forecasting (Li Yaguang, et al., 2017)</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/liyaguang/DCRNN\">A TensorFlow implementation of Diffusion Convolutional Recurrent Neural Network (liyaguang)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of nodes in the graph, e.g. number of stations in NYC-Bike dataset.</li>\n<li><strong>num_diffusion_matrix</strong> – Number of diffusion matrix used in model.</li>\n<li><strong>num_rnn_units</strong> – Number of RNN units.</li>\n<li><strong>num_rnn_layers</strong> – Number of RNN layers</li>\n<li><strong>max_diffusion_step</strong> – Number of diffusion steps</li>\n<li><strong>seq_len</strong> – Input sequence length</li>\n<li><strong>use_curriculum_learning</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – model’s prediction (True) or the previous ground truth in training (False).</li>\n<li><strong>input_dim</strong> – Dimension of the input feature</li>\n<li><strong>output_dim</strong> – Dimension of the output feature</li>\n<li><strong>cl_decay_steps</strong> – When use_curriculum_learning=True, cl_decay_steps is used to adjust the ratio of using ground\ntrue labels, where with more training steps, the ratio drops.</li>\n<li><strong>target_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Output sequence length.</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate</li>\n<li><strong>epsilon</strong> – epsilon in Adam</li>\n<li><strong>optimizer_name</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – ‘sgd’ or ‘Adam’ optimizer</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code, which will be used as filename for saving the model</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’.</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.DCRNN.DCRNN.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><em>init_vars=True</em>, <em>max_to_keep=5</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.DCRNN.DCRNN.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.DeepST\">\n<span id=\"uctb-model-deepst-module\"></span><h2>6.4.3. UCTB.model.DeepST module<a class=\"headerlink\" href=\"#module-UCTB.model.DeepST\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.DeepST.DeepST\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.DeepST.</code><code class=\"descname\">DeepST</code><span class=\"sig-paren\">(</span><em>closeness_len</em>, <em>period_len</em>, <em>trend_len</em>, <em>width</em>, <em>height</em>, <em>external_dim</em>, <em>kernel_size=3</em>, <em>num_conv_filters=64</em>, <em>lr=1e-05</em>, <em>code_version='QuickStart-DeepST'</em>, <em>model_dir='model_dir'</em>, <em>gpu_device='0'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.DeepST.DeepST\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<p>Deep learning-based prediction model for Spatial-Temporal data (DeepST)</p>\n<p>DeepST is composed of three components: 1) temporal dependent\ninstances: describing temporal closeness, period and seasonal\ntrend; 2) convolutional neural networks: capturing near and\nfar spatial dependencies; 3) early and late fusions: fusing\nsimilar and different domains’ data.</p>\n<dl class=\"docutils\">\n<dt>Reference:</dt>\n<dd><ul class=\"first last simple\">\n<li><a class=\"reference external\" href=\"https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf\">DNN-Based Prediction Model for Spatial-Temporal Data (Junbo Zhang et al., 2016)</a>.</li>\n</ul>\n</dd>\n</dl>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>closeness_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of closeness data history. The former consecutive <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> time slots\nof data will be used as closeness history.</li>\n<li><strong>period_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of period data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> days will be used as period history.</li>\n<li><strong>trend_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of trend data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">trend_len</span></code> weeks (every seven days) will be used as trend history.</li>\n<li><strong>width</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The width of grid data.</li>\n<li><strong>height</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The height of grid data.</li>\n<li><strong>externai_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of dimensions of external data.</li>\n<li><strong>kernel_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Kernel size in Convolutional neural networks. Default: 3</li>\n<li><strong>num_conv_filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – the Number of filters in the convolution. Default: 64</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate. Default: 1e-5</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code.</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.DeepST.DeepST.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.DeepST.DeepST.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.GeoMAN\">\n<span id=\"uctb-model-geoman-module\"></span><h2>6.4.4. UCTB.model.GeoMAN module<a class=\"headerlink\" href=\"#module-UCTB.model.GeoMAN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.GeoMAN.GeoMAN\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.GeoMAN.</code><code class=\"descname\">GeoMAN</code><span class=\"sig-paren\">(</span><em>total_sensers</em>, <em>input_dim</em>, <em>external_dim</em>, <em>output_dim</em>, <em>input_steps</em>, <em>output_steps</em>, <em>n_stacked_layers=2</em>, <em>n_encoder_hidden_units=128</em>, <em>n_decoder_hidden_units=128</em>, <em>dropout_rate=0.3</em>, <em>lr=0.001</em>, <em>gc_rate=2.5</em>, <em>code_version='GeoMAN-QuickStart'</em>, <em>model_dir='model_dir'</em>, <em>gpu_device='0'</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GeoMAN.GeoMAN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<p>Multi-level Attention Networks for Geo-sensory Time Series Prediction (GeoMAN)</p>\n<p>GeoMAN consists of two major parts: 1) A multi-level attention mechanism (including both local and global\nspatial attentions in encoder and temporal attention in decoder) to model the dynamic spatio-temporal\ndependencies; 2) A general fusion module to incorporate the external factors from different domains (e.g.,\nmeteorology, time of day and land use).</p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2018/0476.pdf\">GeoMAN: Multi-level Attention Networks for Geo-sensory Time Series Prediction (Liang Yuxuan, et al., 2018)</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/yoshall/GeoMAN\">An easy implement of GeoMAN using TensorFlow (yoshall &amp; CastleLiang)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>total_sensers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of total sensors used in global attention mechanism.</li>\n<li><strong>input_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of dimensions of the target sensor’s input.</li>\n<li><strong>external_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of dimensions of the external features.</li>\n<li><strong>output_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of dimensions of the target sensor’s output.</li>\n<li><strong>input_steps</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of historical input data, a.k.a, input timesteps.</li>\n<li><strong>output_steps</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of steps that need prediction by one piece of history data, a.k.a, output\ntimesteps. Have to be 1 now.</li>\n<li><strong>n_stacked_layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of LSTM layers stacked in both encoder and decoder (These two are the\nsame). Default: 2</li>\n<li><strong>n_encoder_hidden_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of hidden units in each layer of encoder. Default: 128</li>\n<li><strong>n_decoder_hidden_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of hidden units in each layer of decoder. Default: 128</li>\n<li><strong>dropout_rate</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Dropout rate of LSTM layers in both encoder and decoder. Default: 0.3</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate. Default: 0.001</li>\n<li><strong>gc_rate</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – A clipping ratio for all the gradients. This operation normalizes all gradients so that\ntheir L2-norms are less than or equal to <code class=\"docutils literal\"><span class=\"pre\">gc_rate</span></code>. Default: 2.5</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code. Default: ‘GeoMAN-QuickStart’</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’</li>\n<li><strong>**kwargs</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#dict\" title=\"(in Python v3.12)\"><em>dict</em></a>) – Reserved for future use. May be used to pass parameters to class <code class=\"docutils literal\"><span class=\"pre\">BaseModel</span></code>.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.GeoMAN.GeoMAN.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><em>init_vars=True</em>, <em>max_to_keep=5</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GeoMAN.GeoMAN.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GeoMAN.input_transform\">\n<code class=\"descclassname\">UCTB.model.GeoMAN.</code><code class=\"descname\">input_transform</code><span class=\"sig-paren\">(</span><em>local_features</em>, <em>global_features</em>, <em>external_features</em>, <em>targets</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GeoMAN.input_transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Split the model’s inputs from matrices to lists on timesteps axis.</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GeoMAN.split_timesteps\">\n<code class=\"descclassname\">UCTB.model.GeoMAN.</code><code class=\"descname\">split_timesteps</code><span class=\"sig-paren\">(</span><em>inputs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GeoMAN.split_timesteps\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Split the input matrix from (batch, timesteps, input_dim) to a step list ([[batch, input_dim], …, ]).</p>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.HM\">\n<span id=\"uctb-model-hm-module\"></span><h2>6.4.5. UCTB.model.HM module<a class=\"headerlink\" href=\"#module-UCTB.model.HM\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.HM.HM\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.HM.</code><code class=\"descname\">HM</code><span class=\"sig-paren\">(</span><em>c</em>, <em>p</em>, <em>t</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.HM.HM\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Historical Mean. A naive method that simply return average of hisrory data of each time slot.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>c</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of time slots of closeness history.</li>\n<li><strong>p</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of time slots of period history which presents daily feature.</li>\n<li><strong>t</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of time slots of trend history which presents weekly feature.</li>\n<li><strong>that `</strong> (<em>Note</em>) – </li>\n<li><strong>should be considerd in average.</strong> (<em>features</em>) – </li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.HM.HM.predict\">\n<code class=\"descname\">predict</code><span class=\"sig-paren\">(</span><em>closeness_feature</em>, <em>period_feature</em>, <em>trend_feature</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.HM.HM.predict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Give closeness, period and trend history values and then use their averages as predict.</p>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.STMeta\">\n<span id=\"uctb-model-stmeta-module\"></span><h2>6.4.6. UCTB.model.STMeta module<a class=\"headerlink\" href=\"#module-UCTB.model.STMeta\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.STMeta.STMeta\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.STMeta.</code><code class=\"descname\">STMeta</code><span class=\"sig-paren\">(</span><em>num_node</em>, <em>external_dim</em>, <em>closeness_len</em>, <em>period_len</em>, <em>trend_len</em>, <em>input_dim=1</em>, <em>num_graph=1</em>, <em>gcn_k=1</em>, <em>gcn_layers=1</em>, <em>gclstm_layers=1</em>, <em>num_hidden_units=64</em>, <em>num_dense_units=32</em>, <em>graph_merge_gal_units=32</em>, <em>graph_merge_gal_num_heads=2</em>, <em>temporal_merge_gal_units=64</em>, <em>temporal_merge_gal_num_heads=2</em>, <em>st_method='GCLSTM'</em>, <em>temporal_merge='gal'</em>, <em>graph_merge='gal'</em>, <em>output_activation=&lt;function sigmoid&gt;</em>, <em>lr=0.0001</em>, <em>code_version='STMeta-QuickStart'</em>, <em>model_dir='model_dir'</em>, <em>gpu_device='0'</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STMeta.STMeta\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of nodes in the graph, e.g. number of stations in NYC-Bike dataset.</li>\n<li><strong>external_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Dimension of the external feature, e.g. temperature and wind are two dimension.</li>\n<li><strong>closeness_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of closeness data history. The former consecutive <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> time slots</li>\n<li><strong>data will be used as closeness history.</strong> (<em>of</em>) – </li>\n<li><strong>period_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of period data history. The data of exact same time slots in former consecutive</li>\n<li><strong>days will be used as period history.</strong> (<em>period_len</em>) – </li>\n<li><strong>trend_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of trend data history. The data of exact same time slots in former consecutive</li>\n<li><strong>weeks</strong> (<em>trend_len</em>) – </li>\n<li><strong>input_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The dimension of input features. 1 if “with_tpe” (data_loader parameters) = False, otherwise 0.</li>\n<li><strong>num_graph</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of graphs used in STMeta.</li>\n<li><strong>gcn_k</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The highest order of Chebyshev Polynomial approximation in GCN.</li>\n<li><strong>gcn_layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of GCN layers.</li>\n<li><strong>gclstm_layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of STRNN layers, it works on all modes of STMeta such as GCLSTM and DCRNN.</li>\n<li><strong>num_hidden_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of hidden units of RNN.</li>\n<li><strong>num_dense_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of dense units.</li>\n<li><strong>graph_merge_gal_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of units in GAL for merging different graph features.\nOnly works when graph_merge=’gal’</li>\n<li><strong>graph_merge_gal_num_heads</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of heads in GAL for merging different graph features.\nOnly works when graph_merge=’gal’</li>\n<li><strong>temporal_merge_gal_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of units in GAL for merging different temporal features.\nOnly works when temporal_merge=’gal’</li>\n<li><strong>temporal_merge_gal_num_heads</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of heads in GAL for merging different temporal features.\nOnly works when temporal_merge=’gal’</li>\n<li><strong>st_method</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – must in [‘GCLSTM’, ‘DCRNN’, ‘GRU’, ‘LSTM’], which refers to different\nspatial-temporal modeling methods.\n‘GCLSTM’: GCN for modeling spatial feature, LSTM for modeling temporal feature.\n‘DCRNN’: Diffusion Convolution for modeling spatial feature, GRU for modeling temporam frature.\n‘GRU’: Ignore the spatial, and model the temporal feature using GRU\n‘LSTM’: Ignore the spatial, and model the temporal feature using LSTM</li>\n<li><strong>temporal_merge</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – must in [‘gal’, ‘concat’], refers to different temporal merging methods,\n‘gal’: merge using GAL,\n‘concat’: merge by concat and dense</li>\n<li><strong>graph_merge</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – must in [‘gal’, ‘concat’], refers to different graph merging methods,\n‘gal’: merge using GAL,\n‘concat’: merge by concat and dense</li>\n<li><strong>output_activation</strong> (<em>function</em>) – activation function, e.g. tf.nn.tanh</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate. Default: 1e-5</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code, which will be used as filename for saving the model</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’.</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.STMeta.STMeta.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><em>init_vars=True</em>, <em>max_to_keep=5</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STMeta.STMeta.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.ST_MGCN\">\n<span id=\"uctb-model-st-mgcn-module\"></span><h2>6.4.7. UCTB.model.ST_MGCN module<a class=\"headerlink\" href=\"#module-UCTB.model.ST_MGCN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.ST_MGCN.ST_MGCN\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ST_MGCN.</code><code class=\"descname\">ST_MGCN</code><span class=\"sig-paren\">(</span><em>T</em>, <em>input_dim</em>, <em>num_graph</em>, <em>gcl_k</em>, <em>gcl_l</em>, <em>lstm_units</em>, <em>lstm_layers</em>, <em>lr</em>, <em>external_dim</em>, <em>code_version</em>, <em>model_dir</em>, <em>gpu_device</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ST_MGCN.ST_MGCN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"http://www-scf.usc.edu/~yaguang/papers/aaai19_multi_graph_convolution.pdf\">Spatiotemporal multi-graph convolution network for ride-hailing demand forecasting (Geng Xu, et al., 2019)</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/shawnwang-tech/ST-MGCN-pytorch\">A PyTorch implementation of the ST-MGCN model  (shawnwang-tech)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>T</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Input sequence length</li>\n<li><strong>input_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Input feature dimension</li>\n<li><strong>num_graph</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of graphs used in the model.</li>\n<li><strong>gcl_k</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The highest order of Chebyshev Polynomial approximation in GCN.</li>\n<li><strong>gcl_l</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of GCN layers.</li>\n<li><strong>lstm_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of hidden units of RNN.</li>\n<li><strong>lstm_layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of LSTM layers.</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate</li>\n<li><strong>external_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Dimension of the external feature, e.g. temperature and wind are two dimension.</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code, which will be used as filename for saving the model</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’.</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ST_MGCN.ST_MGCN.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><em>init_vars=True</em>, <em>max_to_keep=5</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ST_MGCN.ST_MGCN.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.ST_ResNet\">\n<span id=\"uctb-model-st-resnet-module\"></span><h2>6.4.8. UCTB.model.ST_ResNet module<a class=\"headerlink\" href=\"#module-UCTB.model.ST_ResNet\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.ST_ResNet.ST_ResNet\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ST_ResNet.</code><code class=\"descname\">ST_ResNet</code><span class=\"sig-paren\">(</span><em>width</em>, <em>height</em>, <em>external_dim</em>, <em>closeness_len</em>, <em>period_len</em>, <em>trend_len</em>, <em>num_residual_unit=4</em>, <em>kernel_size=3</em>, <em>lr=5e-05</em>, <em>model_dir='model_dir'</em>, <em>code_version='QuickStart'</em>, <em>conv_filters=64</em>, <em>gpu_device='0'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ST_ResNet.ST_ResNet\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<p>ST-ResNet is a deep-learning model with an end-to-end structure\nbased on unique properties of spatio-temporal data making use of convolution and residual units.</p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://arxiv.org/pdf/1610.00081.pdf\">Deep Spatio-Temporal Residual Networks for Citywide Crowd Flows Prediction (Junbo Zhang et al., 2016)</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/lucktroy/DeepST/tree/master/scripts/papers/AAAI17\">Github repository (lucktroy)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>width</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The width of grid data.</li>\n<li><strong>height</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The height of grid data.</li>\n<li><strong>externai_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of dimensions of external data.</li>\n<li><strong>closeness_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of closeness data history. The former consecutive <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> time slots\nof data will be used as closeness history.</li>\n<li><strong>period_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of period data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> days will be used as period history.</li>\n<li><strong>trend_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of trend data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">trend_len</span></code> weeks (every seven days) will be used as trend history.</li>\n<li><strong>num_residual_unit</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of residual units. Default: 4</li>\n<li><strong>kernel_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Kernel size in Convolutional neural networks. Default: 3</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate. Default: 1e-5</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code.</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’</li>\n<li><strong>conv_filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – the Number of filters in the convolution. Default: 64</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ST_ResNet.ST_ResNet.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ST_ResNet.ST_ResNet.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.XGBoost\">\n<span id=\"uctb-model-xgboost-module\"></span><h2>6.4.9. UCTB.model.XGBoost module<a class=\"headerlink\" href=\"#module-UCTB.model.XGBoost\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.XGBoost.XGBoost\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.XGBoost.</code><code class=\"descname\">XGBoost</code><span class=\"sig-paren\">(</span><em>n_estimators=10</em>, <em>max_depth=5</em>, <em>verbosity=0</em>, <em>objective='reg:squarederror'</em>, <em>eval_metric='rmse'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.XGBoost.XGBoost\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>XGBoost is an optimized distributed gradient boosting machine learning algorithm.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>*n_estimators</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of boosting iterations. Default: 10</li>\n<li><strong>*max_depth</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Maximum tree depth for base learners. Default: 5</li>\n<li><strong>*verbosity</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The degree of verbosity. Valid values are 0 (silent) - 3 (debug). Default: 0</li>\n<li><strong>*objective</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/string.html#module-string\" title=\"(in Python v3.12)\"><em>string</em></a><em> or </em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#callable\" title=\"(in Python v3.12)\"><em>callable</em></a>) – Specify the learning task and the corresponding learning objective or\na custom objective function to be used. Default: <code class=\"docutils literal\"><span class=\"pre\">'reg:squarederror'</span></code></li>\n<li><strong>*eval_metric</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>list of str</em><em>, or </em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#callable\" title=\"(in Python v3.12)\"><em>callable</em></a><em>, </em><em>optional</em>) – If a str, should be a built-in evaluation metric to use. See more in\n<a class=\"reference external\" href=\"https://xgboost.readthedocs.io/en/latest/python/python_api.html\">API Reference of XGBoost Library</a>.\nDefault: <code class=\"docutils literal\"><span class=\"pre\">'rmse'</span></code></li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.XGBoost.XGBoost.fit\">\n<code class=\"descname\">fit</code><span class=\"sig-paren\">(</span><em>X</em>, <em>y</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.XGBoost.XGBoost.fit\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Training method.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>X</strong> (<em>np.ndarray/scipy.sparse/pd.DataFrame/dt.Frame</em>) – The training input samples.</li>\n<li><strong>y</strong> (<em>np.ndarray</em><em>, </em><em>optional</em>) – The target values of training samples.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model.XGBoost.XGBoost.predict\">\n<code class=\"descname\">predict</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.XGBoost.XGBoost.predict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Prediction method.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">Predicted values with shape as [time_slot_num, node_num, 1].</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\">np.ndarray</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.AGCRN\">\n<span id=\"uctb-model-agcrn-module\"></span><h2>6.4.10. UCTB.model.AGCRN module<a class=\"headerlink\" href=\"#module-UCTB.model.AGCRN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.AGCRN.AGCRN\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.AGCRN.</code><code class=\"descname\">AGCRN</code><span class=\"sig-paren\">(</span><em>num_node</em>, <em>input_dim</em>, <em>hidden_dim</em>, <em>output_dim</em>, <em>pred_step</em>, <em>num_layers</em>, <em>default_graph</em>, <em>embed_dim</em>, <em>cheb_k</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.AGCRN.AGCRN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf\">Adaptive graph convolutional recurrent network for traffic forecasting.</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/LeiBAI/AGCRN\">A PyTorch implementation of the AGCRN model  (LeiBAI)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of nodes.</li>\n<li><strong>input_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Input feature dimension.</li>\n<li><strong>hidden_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of hidden units of RNN.</li>\n<li><strong>output_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of dimension of output.</li>\n<li><strong>pred_step</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of steps to predict.</li>\n<li><strong>num_layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of layers of AGCRNCell.</li>\n<li><strong>default_graph</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – Whether to use default graph or not.</li>\n<li><strong>embed_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of dimension of embedding.</li>\n<li><strong>cheb_k</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Order of chebyshev polynomial.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.ASTGCN\">\n<span id=\"uctb-model-astgcn-module\"></span><h2>6.4.11. UCTB.model.ASTGCN module<a class=\"headerlink\" href=\"#module-UCTB.model.ASTGCN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.ASTGCN.ASTGCN_submodule\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">ASTGCN_submodule</code><span class=\"sig-paren\">(</span><em>DEVICE</em>, <em>num_blocks</em>, <em>in_channels</em>, <em>K</em>, <em>num_chev_filter</em>, <em>num_time_filter</em>, <em>time_strides</em>, <em>cheb_polynomials</em>, <em>pred_step</em>, <em>len_input</em>, <em>num_node</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.ASTGCN_submodule\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/3881\">Attention based spatial-temporal graph convolutional networks for traffic flow forecasting..</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/guoshnBJTU/ASTGCN-r-pytorch\">A PyTorch implementation of the ASTGCN model  (guoshnBJTU)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>DEVICE</strong> (<em>torch.device</em>) – Which device use to train.</li>\n<li><strong>num_blocks</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of blocks.</li>\n<li><strong>in_channels</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of input channels.</li>\n<li><strong>K</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Order of chebyshev polynomial.</li>\n<li><strong>num_chev_filter</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of chebyshev filter.</li>\n<li><strong>num_time_filter</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of time filter.</li>\n<li><strong>time_strides</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of time strides.</li>\n<li><strong>cheb_polynomials</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Chebyshev Polynomials.</li>\n<li><strong>pred_step</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of steps of prediction.</li>\n<li><strong>len_input</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of steps of sequence input.</li>\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of nodes.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ASTGCN.ASTGCN_submodule.forward\">\n<code class=\"descname\">forward</code><span class=\"sig-paren\">(</span><em>x</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.ASTGCN_submodule.forward\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>x</strong> – (B, N_nodes, F_in, T_in)</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">(B, N_nodes, T_out)</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.model.ASTGCN.Spatial_Attention_layer\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">Spatial_Attention_layer</code><span class=\"sig-paren\">(</span><em>DEVICE</em>, <em>in_channels</em>, <em>num_of_vertices</em>, <em>num_of_timesteps</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.Spatial_Attention_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p>compute spatial attention scores</p>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ASTGCN.Spatial_Attention_layer.forward\">\n<code class=\"descname\">forward</code><span class=\"sig-paren\">(</span><em>x</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.Spatial_Attention_layer.forward\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>x</strong> – (batch_size, N, F_in, T)</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">(B,N,N)</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.model.ASTGCN.cheb_conv\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">cheb_conv</code><span class=\"sig-paren\">(</span><em>K</em>, <em>cheb_polynomials</em>, <em>in_channels</em>, <em>out_channels</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.cheb_conv\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p>K-order chebyshev graph convolution</p>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ASTGCN.cheb_conv.forward\">\n<code class=\"descname\">forward</code><span class=\"sig-paren\">(</span><em>x</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.cheb_conv.forward\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Chebyshev graph convolution operation\n:param x: (batch_size, N, F_in, T)\n:return: (batch_size, N, F_out, T)</p>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.model.ASTGCN.cheb_conv_withSAt\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">cheb_conv_withSAt</code><span class=\"sig-paren\">(</span><em>K</em>, <em>cheb_polynomials</em>, <em>in_channels</em>, <em>out_channels</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.cheb_conv_withSAt\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p>K-order chebyshev graph convolution</p>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ASTGCN.cheb_conv_withSAt.forward\">\n<code class=\"descname\">forward</code><span class=\"sig-paren\">(</span><em>x</em>, <em>spatial_attention</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.cheb_conv_withSAt.forward\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Chebyshev graph convolution operation\n:param x: (batch_size, N, F_in, T)\n:return: (batch_size, N, F_out, T)</p>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.ASTGCN.cheb_polynomial\">\n<code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">cheb_polynomial</code><span class=\"sig-paren\">(</span><em>L_tilde</em>, <em>K</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.cheb_polynomial\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>compute a list of chebyshev polynomials from T_0 to T_{K-1}</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>L_tilde</strong> (<em>scaled Laplacian</em><em>, </em><em>np.ndarray</em><em>, </em><em>shape</em><em> (</em><em>N</em><em>, </em><em>N</em><em>)</em>) – </li>\n<li><strong>K</strong> (<em>the maximum order of chebyshev polynomials</em>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"><strong>cheb_polynomials</strong></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\"><a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\">list</a>(np.ndarray), length: K, from T_0 to T_{K-1}</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.ASTGCN.make_model\">\n<code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">make_model</code><span class=\"sig-paren\">(</span><em>DEVICE</em>, <em>nb_block</em>, <em>in_channels</em>, <em>K</em>, <em>nb_chev_filter</em>, <em>nb_time_filter</em>, <em>time_strides</em>, <em>L_tilde</em>, <em>num_for_predict</em>, <em>len_input</em>, <em>num_of_vertices</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.make_model\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>DEVICE</strong> – </li>\n<li><strong>nb_block</strong> – </li>\n<li><strong>in_channels</strong> – </li>\n<li><strong>K</strong> – </li>\n<li><strong>nb_chev_filter</strong> – </li>\n<li><strong>nb_time_filter</strong> – </li>\n<li><strong>time_strides</strong> – </li>\n<li><strong>cheb_polynomials</strong> – </li>\n<li><strong>nb_predict_step</strong> – </li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<p>:param len_input\n:return:</p>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.GMAN\">\n<span id=\"uctb-model-gman-module\"></span><h2>6.4.12. UCTB.model.GMAN module<a class=\"headerlink\" href=\"#module-UCTB.model.GMAN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.GMAN\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">GMAN</code><span class=\"sig-paren\">(</span><em>X</em>, <em>TE</em>, <em>SE</em>, <em>P</em>, <em>Q</em>, <em>T</em>, <em>L</em>, <em>K</em>, <em>d</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.GMAN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><blockquote>\n<div><p>References:\n- <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>Gman: A graph multi-attention network for traffic prediction.</p>\n<blockquote>\n<div>&lt;<a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5477\">https://ojs.aaai.org/index.php/AAAI/article/view/5477</a>&gt;`_.</div></blockquote>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://github.com/zhengchuanpan/GMAN\">A Tensorflow implementation of the GMAN model  (Zhengchuanpan)</a>.</li>\n</ul>\n</div></blockquote>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>P</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of history steps.</li>\n<li><strong>Q</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of prediction steps.</li>\n<li><strong>T</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of steps which one day is divided into.</li>\n<li><strong>L</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of STAtt blocks in the encoder/decoder.</li>\n<li><strong>K</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of attention heads.</li>\n<li><strong>d</strong> – Number of dimension of each attention head outputs.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.STEmbedding\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">STEmbedding</code><span class=\"sig-paren\">(</span><em>SE</em>, <em>TE</em>, <em>T</em>, <em>D</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.STEmbedding\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>spatio-temporal embedding</p>\n<p>SE:      [N, D]\nTE:      [batch_size, P + Q, 2] (dayofweek, timeofday)\nT:        num of time steps in one day\nD:        output dims\nretrun: [batch_size, P + Q, N, D]</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.alias_draw\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">alias_draw</code><span class=\"sig-paren\">(</span><em>J</em>, <em>q</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.alias_draw\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Draw sample from a non-uniform discrete distribution using alias sampling.</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.alias_setup\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">alias_setup</code><span class=\"sig-paren\">(</span><em>probs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.alias_setup\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Compute utility lists for non-uniform sampling from discrete distributions.\nRefer to <a class=\"reference external\" href=\"https://hips.seas.harvard.edu/blog/2013/03/03/the-alias-method-efficient-sampling-with-many-discrete-outcomes/\">https://hips.seas.harvard.edu/blog/2013/03/03/the-alias-method-efficient-sampling-with-many-discrete-outcomes/</a>\nfor details</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.gatedFusion\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">gatedFusion</code><span class=\"sig-paren\">(</span><em>HS</em>, <em>HT</em>, <em>D</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.gatedFusion\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>gated fusion</p>\n<p>HS:      [batch_size, num_step, N, D]\nHT:      [batch_size, num_step, N, D]\nD:        output dims\nreturn: [batch_size, num_step, N, D]</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.spatialAttention\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">spatialAttention</code><span class=\"sig-paren\">(</span><em>X</em>, <em>STE</em>, <em>K</em>, <em>d</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.spatialAttention\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>spatial attention mechanism</p>\n<p>X:        [batch_size, num_step, N, D]\nSTE:    [batch_size, num_step, N, D]\nK:        number of attention heads\nd:        dimension of each attention outputs\nreturn: [batch_size, num_step, N, D]</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.temporalAttention\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">temporalAttention</code><span class=\"sig-paren\">(</span><em>X</em>, <em>STE</em>, <em>K</em>, <em>d</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em>, <em>mask=True</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.temporalAttention\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>temporal attention mechanism</p>\n<p>X:        [batch_size, num_step, N, D]\nSTE:    [batch_size, num_step, N, D]\nK:        number of attention heads\nd:        dimension of each attention outputs\nreturn: [batch_size, num_step, N, D]</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.transformAttention\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">transformAttention</code><span class=\"sig-paren\">(</span><em>X</em>, <em>STE_P</em>, <em>STE_Q</em>, <em>K</em>, <em>d</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.transformAttention\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>transform attention mechanism</p>\n<p>X:        [batch_size, P, N, D]\nSTE_P:  [batch_size, P, N, D]\nSTE_Q:  [batch_size, Q, N, D]\nK:        number of attention heads\nd:        dimension of each attention outputs\nreturn: [batch_size, Q, N, D]</p>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"uctb-model-graphwavenet-module\">\n<h2>6.4.13. UCTB.model.GraphWaveNet module<a class=\"headerlink\" href=\"#uctb-model-graphwavenet-module\" title=\"Permalink to this headline\">¶</a></h2>\n<span class=\"target\" id=\"module-UCTB.model.GraphWaveNet\"></span><dl class=\"class\">\n<dt id=\"UCTB.model.GraphWaveNet.gwnet\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.GraphWaveNet.</code><code class=\"descname\">gwnet</code><span class=\"sig-paren\">(</span><em>device</em>, <em>num_node</em>, <em>dropout=0.3</em>, <em>supports=None</em>, <em>gcn_bool=True</em>, <em>addaptadj=True</em>, <em>aptinit=None</em>, <em>in_dim=2</em>, <em>out_dim=12</em>, <em>residual_channels=32</em>, <em>dilation_channels=32</em>, <em>skip_channels=256</em>, <em>end_channels=512</em>, <em>kernel_size=2</em>, <em>blocks=4</em>, <em>layers=2</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GraphWaveNet.gwnet\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2019/0264.pdf\">Graph wavenet for deep spatial-temporal graph modeling.</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/nnzhan/Graph-WaveNet\">A PyTorch implementation of the GraphWaveNet model  (nnzhan)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>device</strong> (<em>torch.device</em>) – Which device use to train.</li>\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of blocks.</li>\n<li><strong>drop_out</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of input channels.</li>\n<li><strong>supports</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Order of chebyshev polynomial.</li>\n<li><strong>gcn_bool</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of chebyshev filter.</li>\n<li><strong>addaptadj</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – Whether to add adaptive adjacent matrix.</li>\n<li><strong>aptinit</strong> (<em>torch.tensor</em>) – Initialization of adjacent matrix.</li>\n<li><strong>in_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of input’s dimension.</li>\n<li><strong>out_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of output’s dimension.</li>\n<li><strong>residual_channels</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of channels after residual module.</li>\n<li><strong>dilation_channels</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of channels after dilation module.</li>\n<li><strong>skip_channels</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of skip channels.</li>\n<li><strong>end_channels</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of end channels.</li>\n<li><strong>kernel_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Kernel Size for dilation convolution.</li>\n<li><strong>blocks</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of block.</li>\n<li><strong>layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of layer.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.STGCN\">\n<span id=\"uctb-model-stgcn-module\"></span><h2>6.4.14. UCTB.model.STGCN module<a class=\"headerlink\" href=\"#module-UCTB.model.STGCN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.build_model\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">build_model</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>n_his</em>, <em>Ks</em>, <em>Kt</em>, <em>blocks</em>, <em>keep_prob</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.build_model\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2018/0505.pdf\">Spatio-temporal graph convolutional networks: A deep learning framework for traffic forecasting.</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/VeritasYin/STGCN_IJCAI-18\">A Tensorflow implementation of the STGCN model  (VeritasYin)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>inputs</strong> – Placeholder.</li>\n<li><strong>n_his</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Size of historical records for training.</li>\n<li><strong>Ks</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Kernel size of spatial convolution.</li>\n<li><strong>Kt</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Kernel size of temporal convolution.</li>\n<li><strong>blocks</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – Channel configs of st_conv blocks.</li>\n<li><strong>keep_prob</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Placeholder.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.cheb_poly_approx\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">cheb_poly_approx</code><span class=\"sig-paren\">(</span><em>L</em>, <em>Ks</em>, <em>n</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.cheb_poly_approx\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Chebyshev polynomials approximation function.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>L</strong> – np.matrix, [n_route, n_route], graph Laplacian.</li>\n<li><strong>Ks</strong> – int, kernel size of spatial convolution.</li>\n<li><strong>n</strong> – int, number of routes / size of graph.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">np.ndarray, [n_route, Ks*n_route].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.fully_con_layer\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">fully_con_layer</code><span class=\"sig-paren\">(</span><em>x</em>, <em>n</em>, <em>channel</em>, <em>scope</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.fully_con_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Fully connected layer: maps multi-channels to one.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, [batch_size, 1, n_route, channel].</li>\n<li><strong>n</strong> – int, number of route / size of graph.</li>\n<li><strong>channel</strong> – channel size of input x.</li>\n<li><strong>scope</strong> – str, variable scope.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, 1, n_route, 1].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.gconv\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">gconv</code><span class=\"sig-paren\">(</span><em>x</em>, <em>theta</em>, <em>Ks</em>, <em>c_in</em>, <em>c_out</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.gconv\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><dl class=\"docutils\">\n<dt>Spectral-based graph convolution function.</dt>\n<dd>x: tensor, [batch_size, n_route, c_in].\ntheta: tensor, [Ks*c_in, c_out], trainable kernel parameters.\nKs: int, kernel size of graph convolution.\nc_in: int, size of input channel.\nc_out: int, size of output channel.</dd>\n</dl>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">tensor, [batch_size, n_route, c_out].</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.gen_batch\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">gen_batch</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>batch_size</em>, <em>dynamic_batch=False</em>, <em>shuffle=False</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.gen_batch\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Data iterator in batch.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>inputs</strong> – np.ndarray, [len_seq, n_frame, n_route, C_0], standard sequence units.</li>\n<li><strong>batch_size</strong> – int, the size of batch.</li>\n<li><strong>dynamic_batch</strong> – bool, whether changes the batch size in the last batch if its length is less than the default.</li>\n<li><strong>shuffle</strong> – bool, whether shuffle the batches.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.layer_norm\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">layer_norm</code><span class=\"sig-paren\">(</span><em>x</em>, <em>scope</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.layer_norm\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Layer normalization function.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, [batch_size, time_step, n_route, channel].</li>\n<li><strong>scope</strong> – str, variable scope.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, time_step, n_route, channel].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.output_layer\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">output_layer</code><span class=\"sig-paren\">(</span><em>x</em>, <em>T</em>, <em>scope</em>, <em>act_func='GLU'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.output_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Output layer: temporal convolution layers attach with one fully connected layer,\nwhich map outputs of the last st_conv block to a single-step prediction.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, [batch_size, time_step, n_route, channel].</li>\n<li><strong>T</strong> – int, kernel size of temporal convolution.</li>\n<li><strong>scope</strong> – str, variable scope.</li>\n<li><strong>act_func</strong> – str, activation function.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, 1, n_route, 1].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.spatio_conv_layer\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">spatio_conv_layer</code><span class=\"sig-paren\">(</span><em>x</em>, <em>Ks</em>, <em>c_in</em>, <em>c_out</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.spatio_conv_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Spatial graph convolution layer.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, [batch_size, time_step, n_route, c_in].</li>\n<li><strong>Ks</strong> – int, kernel size of spatial convolution.</li>\n<li><strong>c_in</strong> – int, size of input channel.</li>\n<li><strong>c_out</strong> – int, size of output channel.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, time_step, n_route, c_out].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.st_conv_block\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">st_conv_block</code><span class=\"sig-paren\">(</span><em>x</em>, <em>Ks</em>, <em>Kt</em>, <em>channels</em>, <em>scope</em>, <em>keep_prob</em>, <em>act_func='GLU'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.st_conv_block\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Spatio-temporal convolutional block, which contains two temporal gated convolution layers\nand one spatial graph convolution layer in the middle.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, batch_size, time_step, n_route, c_in].</li>\n<li><strong>Ks</strong> – int, kernel size of spatial convolution.</li>\n<li><strong>Kt</strong> – int, kernel size of temporal convolution.</li>\n<li><strong>channels</strong> – list, channel configs of a single st_conv block.</li>\n<li><strong>scope</strong> – str, variable scope.</li>\n<li><strong>keep_prob</strong> – placeholder, prob of dropout.</li>\n<li><strong>act_func</strong> – str, activation function.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, time_step, n_route, c_out].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.temporal_conv_layer\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">temporal_conv_layer</code><span class=\"sig-paren\">(</span><em>x</em>, <em>Kt</em>, <em>c_in</em>, <em>c_out</em>, <em>act_func='relu'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.temporal_conv_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Temporal convolution layer.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, [batch_size, time_step, n_route, c_in].</li>\n<li><strong>Kt</strong> – int, kernel size of temporal convolution.</li>\n<li><strong>c_in</strong> – int, size of input channel.</li>\n<li><strong>c_out</strong> – int, size of output channel.</li>\n<li><strong>act_func</strong> – str, activation function.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, time_step-Kt+1, n_route, c_out].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.variable_summaries\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">variable_summaries</code><span class=\"sig-paren\">(</span><em>var</em>, <em>v_name</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.variable_summaries\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Attach summaries to a Tensor (for TensorBoard visualization).\nRef: <a class=\"reference external\" href=\"https://zhuanlan.zhihu.com/p/33178205\">https://zhuanlan.zhihu.com/p/33178205</a></p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>var</strong> – tf.Variable().</li>\n<li><strong>v_name</strong> – str, name of the variable.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.STSGCN\">\n<span id=\"uctb-model-stsgcn-module\"></span><h2>6.4.15. UCTB.model.STSGCN module<a class=\"headerlink\" href=\"#module-UCTB.model.STSGCN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.construct_adj\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">construct_adj</code><span class=\"sig-paren\">(</span><em>A</em>, <em>steps</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.construct_adj\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>construct a bigger adjacency matrix using the given matrix</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>A</strong> (<em>np.ndarray</em><em>, </em><em>adjacency matrix</em><em>, </em><em>shape is</em><em> (</em><em>N</em><em>, </em><em>N</em><em>)</em>) – </li>\n<li><strong>steps</strong> (<em>how many times of the does the new adj mx bigger than A</em>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"><strong>new adjacency matrix</strong></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">csr_matrix, shape is (N * steps, N * steps)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.gcn_operation\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">gcn_operation</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>num_of_filter</em>, <em>num_of_features</em>, <em>num_of_vertices</em>, <em>activation</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.gcn_operation\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>graph convolutional operation, a simple GCN we defined in paper</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>B</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>adj</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>3N</em><em>)</em>) – </li>\n<li><strong>num_of_filter</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C'</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'GLU'</em><em>, </em><em>'relu'}</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (3N, B, C’)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.get_adjacency_matrix\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">get_adjacency_matrix</code><span class=\"sig-paren\">(</span><em>distance_df_filename</em>, <em>num_of_vertices</em>, <em>type_='connectivity'</em>, <em>id_filename=None</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.get_adjacency_matrix\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>distance_df_filename</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>path of the csv file contains edges information</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>the number of vertices</em>) – </li>\n<li><strong>type</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{connectivity</em><em>, </em><em>distance}</em>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"><strong>A</strong></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">np.ndarray, adjacency matrix</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.output_layer\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">output_layer</code><span class=\"sig-paren\">(</span><em>data</em>, <em>num_of_vertices</em>, <em>input_length</em>, <em>num_of_features</em>, <em>num_of_filters=128</em>, <em>predict_length=12</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.output_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>B</em><em>, </em><em>T</em><em>, </em><em>N</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>input_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of time series</em><em>, </em><em>T</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>num_of_filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C'</em>) – </li>\n<li><strong>predict_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of predicted time series</em><em>, </em><em>T'</em>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (B, T’, N)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.position_embedding\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">position_embedding</code><span class=\"sig-paren\">(</span><em>data</em>, <em>input_length</em>, <em>num_of_vertices</em>, <em>embedding_size</em>, <em>temporal=True</em>, <em>spatial=True</em>, <em>init=&lt;mxnet.initializer.Xavier object&gt;</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.position_embedding\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>B</em><em>, </em><em>T</em><em>, </em><em>N</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>input_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of time series</em><em>, </em><em>T</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>embedding_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>spatial</strong> (<em>temporal</em><em>,</em>) – </li>\n<li><strong>init</strong> (<em>mx.initializer.Initializer</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"><strong>data</strong></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (B, T, N, C)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.sthgcn_layer_individual\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">sthgcn_layer_individual</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>T</em>, <em>num_of_vertices</em>, <em>num_of_features</em>, <em>filters</em>, <em>activation</em>, <em>temporal_emb=True</em>, <em>spatial_emb=True</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.sthgcn_layer_individual\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>STSGCL, multiple individual STSGCMs</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>B</em><em>, </em><em>T</em><em>, </em><em>N</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>adj</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>3N</em><em>)</em>) – </li>\n<li><strong>T</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of time series</em><em>, </em><em>T</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a><em>[</em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>]</em><em>, </em><em>list of C'</em>) – </li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'GLU'</em><em>, </em><em>'relu'}</em>) – </li>\n<li><strong>spatial_emb</strong> (<em>temporal_emb</em><em>,</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (B, T-2, N, C’)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.sthgcn_layer_sharing\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">sthgcn_layer_sharing</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>T</em>, <em>num_of_vertices</em>, <em>num_of_features</em>, <em>filters</em>, <em>activation</em>, <em>temporal_emb=True</em>, <em>spatial_emb=True</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.sthgcn_layer_sharing\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>STSGCL, multiple a sharing STSGCM</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>B</em><em>, </em><em>T</em><em>, </em><em>N</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>adj</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>3N</em><em>)</em>) – </li>\n<li><strong>T</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of time series</em><em>, </em><em>T</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a><em>[</em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>]</em><em>, </em><em>list of C'</em>) – </li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'GLU'</em><em>, </em><em>'relu'}</em>) – </li>\n<li><strong>spatial_emb</strong> (<em>temporal_emb</em><em>,</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (B, T-2, N, C’)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.stsgcl\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">stsgcl</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>T</em>, <em>num_of_vertices</em>, <em>num_of_features</em>, <em>filters</em>, <em>module_type</em>, <em>activation</em>, <em>temporal_emb=True</em>, <em>spatial_emb=True</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.stsgcl\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>STSGCL</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>B</em><em>, </em><em>T</em><em>, </em><em>N</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>adj</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>3N</em><em>)</em>) – </li>\n<li><strong>T</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of time series</em><em>, </em><em>T</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a><em>[</em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>]</em><em>, </em><em>list of C'</em>) – </li>\n<li><strong>module_type</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'sharing'</em><em>, </em><em>'individual'}</em>) – </li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'GLU'</em><em>, </em><em>'relu'}</em>) – </li>\n<li><strong>spatial_emb</strong> (<em>temporal_emb</em><em>,</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (B, T-2, N, C’)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.stsgcm\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">stsgcm</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>filters</em>, <em>num_of_features</em>, <em>num_of_vertices</em>, <em>activation</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.stsgcm\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>STSGCM, multiple stacked gcn layers with cropping and max operation</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>B</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>adj</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>3N</em><em>)</em>) – </li>\n<li><strong>filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a><em>[</em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>]</em><em>, </em><em>list of C'</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'GLU'</em><em>, </em><em>'relu'}</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (N, B, C’)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.stsgcn\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">stsgcn</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>label</em>, <em>input_length</em>, <em>num_of_vertices</em>, <em>num_of_features</em>, <em>filter_list</em>, <em>module_type</em>, <em>activation</em>, <em>use_mask=True</em>, <em>mask_init_value=None</em>, <em>temporal_emb=True</em>, <em>spatial_emb=True</em>, <em>prefix=''</em>, <em>rho=1</em>, <em>predict_length=12</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.stsgcn\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5438\">Spatial-temporal synchronous graph convolutional networks: A new framework for spatial-temporal network data forecasting.</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/Davidham3/STSGCN\">A Mxnet implementation of the stsgcn model  (Davidham3)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>data</strong> (<em>mxnet.sym</em>) – Input data.</li>\n<li><strong>adj</strong> (<em>mxnet.sym</em>) – Adjacent matrix.</li>\n<li><strong>label</strong> (<em>mxnet.sym</em>) – Prediction label.</li>\n<li><strong>input_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Length of input data.</li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of vertices in the graph.</li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of features of each vertice.</li>\n<li><strong>filter_list</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – Filters.</li>\n<li><strong>module_type</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Whether sharing weights.</li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Choose which activate function.</li>\n<li><strong>use_mask</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – Whether we use mask.</li>\n<li><strong>mask_init_value</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Initial value of mask.</li>\n<li><strong>temporal_emb</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – Whether to use temporal embedding.</li>\n<li><strong>spatial_emb</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – Whether to use spatial embedding.</li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – String prefix of mask.</li>\n<li><strong>rho</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Hyperparameters used to calculate huber loss.</li>\n<li><strong>predict_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Length of prediction.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.evaluation.html\" class=\"btn btn-neutral float-right\" title=\"6.5. UCTB.evaluation package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.model_unit.html\" class=\"btn btn-neutral\" title=\"6.3. UCTB.model_unit package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/UCTB.model_unit.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.3. UCTB.model_unit package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.4. UCTB.model package\" href=\"UCTB.model.html\"/>\n        <link rel=\"prev\" title=\"6.2. UCTB.preprocess package\" href=\"UCTB.preprocess.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.3. UCTB.model_unit package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.model_unit.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-model-unit-package\">\n<h1>6.3. UCTB.model_unit package<a class=\"headerlink\" href=\"#uctb-model-unit-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.model_unit.BaseModel\">\n<span id=\"uctb-model-unit-basemodel-module\"></span><h2>6.3.1. UCTB.model_unit.BaseModel module<a class=\"headerlink\" href=\"#module-UCTB.model_unit.BaseModel\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model_unit.BaseModel.</code><code class=\"descname\">BaseModel</code><span class=\"sig-paren\">(</span><em>code_version</em>, <em>model_dir</em>, <em>gpu_device</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<dl class=\"docutils\">\n<dt>BaseModel is the base class for many models, such as STMeta, ST-MGCN and ST_ResNet,</dt>\n<dd>you can also build your own model using this class. More information can be found in tutorial.</dd>\n</dl>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>code_version</strong> – Current version of this model code, which will be used as filename for saving the model.</li>\n<li><strong>model_dir</strong> – The directory to store model files. Default:’model_dir’.</li>\n<li><strong>gpu_device</strong> – To specify the GPU to use. Default: ‘0’.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><em>init_vars=True</em>, <em>max_to_keep=5</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><dl class=\"docutils\">\n<dt>Args</dt>\n<dd>init_vars(bool): auto init the parameters if set to True, else no parameters will be initialized.\nmax_to_keep: max file to keep, which equals to max_to_keep in tf.train.Saver.</dd>\n</dl>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.close\">\n<code class=\"descname\">close</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.close\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Close the session, release memory.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.fit\">\n<code class=\"descname\">fit</code><span class=\"sig-paren\">(</span><em>sequence_length</em>, <em>output_names=('loss'</em>, <em>)</em>, <em>op_names=('train_op'</em>, <em>)</em>, <em>evaluate_loss_name='loss'</em>, <em>batch_size=64</em>, <em>max_epoch=10000</em>, <em>validate_ratio=0.1</em>, <em>shuffle_data=True</em>, <em>early_stop_method='t-test'</em>, <em>early_stop_length=10</em>, <em>early_stop_patience=0.1</em>, <em>verbose=True</em>, <em>save_model=True</em>, <em>save_model_name=None</em>, <em>auto_load_model=True</em>, <em>return_outputs=False</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.fit\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>sequence_length</strong> – int, the sequence length which is use in mini-batch training</li>\n<li><strong>output_names</strong> – list, [output_tensor1_name, output_tensor1_name, …]</li>\n<li><strong>op_names</strong> – list, [operation1_name, operation2_name, …]</li>\n<li><strong>evaluate_loss_name</strong> – str, should be on of the output_names, evaluate_loss_name was use in\nearly-stopping</li>\n<li><strong>batch_size</strong> – int, default 64, batch size</li>\n<li><strong>max_epoch</strong> – int, default 10000, max number of epochs</li>\n<li><strong>validate_ratio</strong> – float, default 0.1, the ration of data that will be used as validation dataset</li>\n<li><strong>shuffle_data</strong> – bool, default True, whether shuffle data in mini-batch train</li>\n<li><strong>early_stop_method</strong> – should be ‘t-test’ or ‘naive’, both method are explained in train.EarlyStopping</li>\n<li><strong>early_stop_length</strong> – int, must provide when early_stop_method=’t-test’</li>\n<li><strong>early_stop_patience</strong> – int, must provide when early_stop_method=’naive’</li>\n<li><strong>verbose</strong> – Bool, flag to print training information or not</li>\n<li><strong>save_model</strong> – Bool, flog to save model or not</li>\n<li><strong>save_model_name</strong> – String, filename for saving the model, which will overwrite the code_version.</li>\n<li><strong>auto_load_model</strong> – Bool, the “fit” function will automatically load the model from disk, if exists,\nbefore the training. Set to False to disable the auto-loading.</li>\n<li><strong>return_outputs</strong> – Bool, set True to return the training log, otherwise nothing will be returned</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.load\">\n<code class=\"descname\">load</code><span class=\"sig-paren\">(</span><em>subscript</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.load\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>subscript</strong> – String, subscript will be appended to the code version as the model file name,\nand load the corresponding model using this filename</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.load_event_scalar\">\n<code class=\"descname\">load_event_scalar</code><span class=\"sig-paren\">(</span><em>scalar_name='val_loss'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.load_event_scalar\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>scalar_name</strong> – load the corresponding scalar name from tensorboard-file,\ne.g. load_event_scalar(‘val_loss)</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.predict\">\n<code class=\"descname\">predict</code><span class=\"sig-paren\">(</span><em>sequence_length</em>, <em>output_names=('prediction'</em>, <em>)</em>, <em>cache_volume=64</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.predict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>output_names</strong> – list, [output_tensor_name1, output_tensor_name2, …]</li>\n<li><strong>sequence_length</strong> – int, the length of sequence, which is use in mini-batch training</li>\n<li><strong>cache_volume</strong> – int, default 64, we need to set cache_volume if the cache can not hold\nthe whole validation dataset</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<p>:param : return: outputs_dict: dict, like {output_tensor1_name: output_tensor1_value, …}</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.save\">\n<code class=\"descname\">save</code><span class=\"sig-paren\">(</span><em>subscript</em>, <em>global_step</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.save\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>subscript</strong> – String, subscript will be appended to the code version as the model filename,\nand save the corresponding model using this filename</li>\n<li><strong>global_step</strong> – Int, current training steps</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model_unit.DCRNN_CELL\">\n<span id=\"uctb-model-unit-dcrnn-cell-module\"></span><h2>6.3.2. UCTB.model_unit.DCRNN_CELL module<a class=\"headerlink\" href=\"#module-UCTB.model_unit.DCRNN_CELL\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model_unit.DCRNN_CELL.DCGRUCell\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model_unit.DCRNN_CELL.</code><code class=\"descname\">DCGRUCell</code><span class=\"sig-paren\">(</span><em>num_units</em>, <em>input_dim</em>, <em>num_graphs</em>, <em>supports</em>, <em>max_diffusion_step</em>, <em>num_node</em>, <em>num_proj=None</em>, <em>activation=&lt;function tanh&gt;</em>, <em>reuse=None</em>, <em>use_gc_for_ru=True</em>, <em>name=None</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.DCRNN_CELL.DCGRUCell\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">tensorflow.python.ops.rnn_cell_impl.RNNCell</span></code></p>\n<p>Graph Convolution Gated Recurrent Unit cell.</p>\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.DCRNN_CELL.DCGRUCell.call\">\n<code class=\"descname\">call</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.DCRNN_CELL.DCGRUCell.call\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.DCRNN_CELL.DCGRUCell.compute_output_shape\">\n<code class=\"descname\">compute_output_shape</code><span class=\"sig-paren\">(</span><em>input_shape</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.DCRNN_CELL.DCGRUCell.compute_output_shape\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.model_unit.DCRNN_CELL.DCGRUCell.output_size\">\n<code class=\"descname\">output_size</code><a class=\"headerlink\" href=\"#UCTB.model_unit.DCRNN_CELL.DCGRUCell.output_size\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.model_unit.DCRNN_CELL.DCGRUCell.state_size\">\n<code class=\"descname\">state_size</code><a class=\"headerlink\" href=\"#UCTB.model_unit.DCRNN_CELL.DCGRUCell.state_size\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model_unit.GraphModelLayers\">\n<span id=\"uctb-model-unit-graphmodellayers-module\"></span><h2>6.3.3. UCTB.model_unit.GraphModelLayers module<a class=\"headerlink\" href=\"#module-UCTB.model_unit.GraphModelLayers\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GAL\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model_unit.GraphModelLayers.</code><code class=\"descname\">GAL</code><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GAL\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>This class provides static methods for adding Graph Attention Layer.</p>\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GAL.add_ga_layer_matrix\">\n<em class=\"property\">static </em><code class=\"descname\">add_ga_layer_matrix</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>units</em>, <em>num_head</em>, <em>activation=&lt;function tanh&gt;</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GAL.add_ga_layer_matrix\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>This method use Multi-head attention technique to add Graph Attention Layer.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>input</strong> (<em>ndarray</em>) – The set of node features data, with shape [batch, num_node, num_featuer].</li>\n<li><strong>unit</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of merge_gal_units used in GAL.</li>\n<li><strong>num_head</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of multi-head used in GAL.</li>\n<li><strong>activation</strong> (<em>function</em>) – activation function. default:tf.nn.tanh.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\">The weight matrix after softmax function.\ngc_output: The final GAL aggregated feature representation from input feature.</p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">alpha</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GAL.add_residual_ga_layer\">\n<em class=\"property\">static </em><code class=\"descname\">add_residual_ga_layer</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>units</em>, <em>num_head</em>, <em>activation=&lt;function tanh&gt;</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GAL.add_residual_ga_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Call the add_ga_layer_matrix function to build the Graph Attention Layer,\nand add the residual layer to optimize the deep neural network.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GAL.attention_merge_weight\">\n<em class=\"property\">static </em><code class=\"descname\">attention_merge_weight</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>units</em>, <em>num_head</em>, <em>activation=&lt;function leaky_relu&gt;</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GAL.attention_merge_weight\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GCL\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model_unit.GraphModelLayers.</code><code class=\"descname\">GCL</code><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GCL\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>This class provides static methods for adding Graph Convolution Layer.</p>\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GCL.add_gc_layer\">\n<em class=\"property\">static </em><code class=\"descname\">add_gc_layer</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>gcn_k</em>, <em>laplacian_matrix</em>, <em>output_size</em>, <em>dtype=tf.float32</em>, <em>use_bias=True</em>, <em>trainable=True</em>, <em>initializer=None</em>, <em>regularizer=None</em>, <em>activation=&lt;function tanh&gt;</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GCL.add_gc_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>Input</strong> (<em>ndarray</em>) – The input features with shape [batch, num_node, num_feature].</li>\n<li><strong>gcn_k</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The highest order of Chebyshev Polynomial approximation in GCN.</li>\n<li><strong>laplacian_matrix</strong> (<em>ndarray</em>) – Laplacian matrix used in GCN, with shape [num_node, num_node].</li>\n<li><strong>output_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of output channels.</li>\n<li><strong>dtype</strong> – Data type. default:tf.float32.</li>\n<li><strong>use_bias</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – It determines whether to add bias in the output. default:True.</li>\n<li><strong>trainable</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – It determines whether <cite>weights</cite> tensor can be trained. default:True.</li>\n<li><strong>initializer</strong> – It determines whether the “weight” tensor is initialized. default:None.</li>\n<li><strong>regularizer</strong> – It determines whether the “weight” tensor is regularized. default:None.</li>\n<li><strong>activation</strong> (<em>function</em>) – activation function. default:tf.nn.tanh.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">Returns the result of convolution of <cite>inputs</cite> and <cite>laplacian_matrix</cite></p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GCL.add_multi_gc_layers\">\n<em class=\"property\">static </em><code class=\"descname\">add_multi_gc_layers</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>gcn_k</em>, <em>gcn_l</em>, <em>output_size</em>, <em>laplacian_matrix</em>, <em>activation=&lt;function tanh&gt;</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GCL.add_multi_gc_layers\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Call add_gc_layer function to add multi Graph Convolution Layer.`gcn_l` is the number of layers added.</p>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model_unit.ST_RNN\">\n<span id=\"uctb-model-unit-st-rnn-module\"></span><h2>6.3.4. UCTB.model_unit.ST_RNN module<a class=\"headerlink\" href=\"#module-UCTB.model_unit.ST_RNN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model_unit.ST_RNN.GCLSTMCell\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model_unit.ST_RNN.</code><code class=\"descname\">GCLSTMCell</code><span class=\"sig-paren\">(</span><em>units</em>, <em>num_node</em>, <em>laplacian_matrix</em>, <em>gcn_k=1</em>, <em>gcn_l=1</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.ST_RNN.GCLSTMCell\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">tensorflow.python.keras.layers.recurrent.LSTMCell</span></code></p>\n<p>GCLSTMCell is one of our implemented ST-RNN models in handling the spatial and temporal features.\nWe performed GCN on both LSTM inputs and hidden-states. The code is inherited from tf.keras.layers.LSTMCell,\nthus it can be used almost the same as LSTMCell except that you need to provide the GCN parameters\nin the __init__ function.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – number of units of LSTM</li>\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – number of nodes in the graph</li>\n<li><strong>laplacian_matrix</strong> (<em>ndarray</em>) – laplacian matrix used in GCN, with shape [num_node, num_node]</li>\n<li><strong>gcn_k</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – highest order of Chebyshev Polynomial approximation in GCN</li>\n<li><strong>gcn_l</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – number of GCN layers</li>\n<li><strong>kwargs</strong> – other parameters supported by LSTMCell, such as activation, kernel_initializer … and so on.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.model.html\" class=\"btn btn-neutral float-right\" title=\"6.4. UCTB.model package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.preprocess.html\" class=\"btn btn-neutral\" title=\"6.2. UCTB.preprocess package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/UCTB.preprocess.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.2. UCTB.preprocess package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.3. UCTB.model_unit package\" href=\"UCTB.model_unit.html\"/>\n        <link rel=\"prev\" title=\"6.1. UCTB.dataset package\" href=\"UCTB.dataset.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.2. UCTB.preprocess package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.preprocess.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-preprocess-package\">\n<h1>6.2. UCTB.preprocess package<a class=\"headerlink\" href=\"#uctb-preprocess-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"uctb-preprocess-graphgenerator-module\">\n<h2>6.2.1. UCTB.preprocess.GraphGenerator module<a class=\"headerlink\" href=\"#uctb-preprocess-graphgenerator-module\" title=\"Permalink to this headline\">¶</a></h2>\n<span class=\"target\" id=\"module-UCTB.preprocess.GraphGenerator\"></span><dl class=\"class\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.GraphGenerator.</code><code class=\"descname\">GraphGenerator</code><span class=\"sig-paren\">(</span><em>data_loader</em>, <em>graph='Correlation'</em>, <em>threshold_distance=1000</em>, <em>threshold_correlation=0</em>, <em>threshold_interaction=500</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>This class is used to build graphs.\nAdajacent matrix and lapalace matrix will be stored in self.AM and self.LM.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>data_loader</strong> (<a class=\"reference internal\" href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader\" title=\"UCTB.dataset.data_loader.NodeTrafficLoader\"><em>NodeTrafficLoader</em></a>) – data_loader object.</li>\n<li><strong>graph</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Types of graphs used in neural methods. Graphs should be a subset of { <code class=\"docutils literal\"><span class=\"pre\">'Correlation'</span></code>,\n<code class=\"docutils literal\"><span class=\"pre\">'Distance'</span></code>, <code class=\"docutils literal\"><span class=\"pre\">'Interaction'</span></code>, <code class=\"docutils literal\"><span class=\"pre\">'Line'</span></code>, <code class=\"docutils literal\"><span class=\"pre\">'Neighbor'</span></code>, <code class=\"docutils literal\"><span class=\"pre\">'Transfer'</span></code> } and concatenated by <code class=\"docutils literal\"><span class=\"pre\">'-'</span></code>,\nand <em>dataset</em> should have data of selected graphs. Default: <code class=\"docutils literal\"><span class=\"pre\">'Correlation'</span></code></li>\n<li><strong>threshold_distance</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Used in building of distance graph. If distance of two nodes in meters is larger\nthan <code class=\"docutils literal\"><span class=\"pre\">threshold_distance</span></code>, the corresponding position of the distance graph will be 1 and otherwise\n0.the corresponding Default: 1000</li>\n<li><strong>threshold_correlation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Used in building of correlation graph. If the Pearson correlation coefficient is\nlarger than <code class=\"docutils literal\"><span class=\"pre\">threshold_correlation</span></code>, the corresponding position of the correlation graph will be 1\nand otherwise 0. Default: 0</li>\n<li><strong>threshold_interaction</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Used in building of interatction graph. If in the latest 12 months, the number of\ntimes of interaction between two nodes is larger than <code class=\"docutils literal\"><span class=\"pre\">threshold_interaction</span></code>, the corresponding position\nof the interaction graph will be 1 and otherwise 0. Default: 500</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"attribute\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.AM\">\n<code class=\"descname\">AM</code><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.AM\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>array</em> – Adajacent matrices of graphs.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.LM\">\n<code class=\"descname\">LM</code><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.LM\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>array</em> – Laplacian matrices of graphs.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.adjacent_to_laplacian\">\n<em class=\"property\">static </em><code class=\"descname\">adjacent_to_laplacian</code><span class=\"sig-paren\">(</span><em>adjacent_matrix</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.adjacent_to_laplacian\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Turn adjacent_matrix into Laplace matrix.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.correlation_adjacent\">\n<em class=\"property\">static </em><code class=\"descname\">correlation_adjacent</code><span class=\"sig-paren\">(</span><em>traffic_data</em>, <em>threshold</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.correlation_adjacent\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Calculate correlation graph based on pearson coefficient.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>traffic_data</strong> (<em>ndarray</em>) – numpy array with shape [sequence_length, num_node].</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – float between [-1, 1], nodes with Pearson Correlation coefficient\nlarger than this threshold will be linked together.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.distance_adjacent\">\n<code class=\"descname\">distance_adjacent</code><span class=\"sig-paren\">(</span><em>lat_lng_list</em>, <em>threshold</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.distance_adjacent\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Calculate distance graph based on geographic distance.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>lat_lng_list</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – A list of geographic locations. The format of each element\nin the list is [latitude, longitude].</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – (meters) nodes with geographic distacne smaller than this\nthreshold will be linked together.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.haversine\">\n<em class=\"property\">static </em><code class=\"descname\">haversine</code><span class=\"sig-paren\">(</span><em>lat1</em>, <em>lon1</em>, <em>lat2</em>, <em>lon2</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.haversine\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Calculate the great circle distance between two points\non the earth (specified in decimal degrees)</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.interaction_adjacent\">\n<em class=\"property\">static </em><code class=\"descname\">interaction_adjacent</code><span class=\"sig-paren\">(</span><em>interaction_matrix</em>, <em>threshold</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.interaction_adjacent\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Binarize interaction_matrix based on threshold.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>interaction_matrix</strong> (<em>ndarray</em>) – <p>with shape [num_node, num_node], where each\nelement represents the number of interactions during a certain time,</p>\n<blockquote>\n<div>e.g. 6 monthes, between the corresponding nodes.</div></blockquote>\n</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a><em> or </em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – nodes with number of interactions between them\ngreater than this threshold will be linked together.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.GraphGenerator.scaled_Laplacian_ASTGCN\">\n<code class=\"descclassname\">UCTB.preprocess.GraphGenerator.</code><code class=\"descname\">scaled_Laplacian_ASTGCN</code><span class=\"sig-paren\">(</span><em>W</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.scaled_Laplacian_ASTGCN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>compute     ilde{L}</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>W</strong><strong>(</strong><strong>np.ndarray</strong><strong>)</strong> (<em>shape is</em><em> (</em><em>num_node</em><em>, </em><em>num_node</em><em>)</em><em></em>) – </td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><strong>scaled_Laplacian_ASTGCN</strong></td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\">np.ndarray, shape (num_node, num_node)</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.GraphGenerator.scaled_laplacian_STGCN\">\n<code class=\"descclassname\">UCTB.preprocess.GraphGenerator.</code><code class=\"descname\">scaled_laplacian_STGCN</code><span class=\"sig-paren\">(</span><em>W</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.scaled_laplacian_STGCN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Normalized graph Laplacian function.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>W</strong> (<em>np.ndarray</em>) – [num_node, num_node], weighted adjacency matrix of G.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">Scaled laplacian matrix.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">np.matrix, [num_node, num_node].</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.preprocess.preprocessor\">\n<span id=\"uctb-preprocess-preprocessor-module\"></span><h2>6.2.2. UCTB.preprocess.preprocessor module<a class=\"headerlink\" href=\"#module-UCTB.preprocess.preprocessor\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.MaxMinNormalizer\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">MaxMinNormalizer</code><span class=\"sig-paren\">(</span><em>X</em>, <em>method='all'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.MaxMinNormalizer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"#UCTB.preprocess.preprocessor.Normalizer\" title=\"UCTB.preprocess.preprocessor.Normalizer\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.preprocess.preprocessor.Normalizer</span></code></a></p>\n<p>This class can help normalize and denormalize data using maximum and minimum of data by calling transform and inverse_transform method.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>X</strong> (<em>ndarray</em>) – Data which normalizer extracts characteristics from.</li>\n<li><strong>method</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Parameter to choose in which way the input data will be processed.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.MaxMinNormalizer.inverse_transform\">\n<code class=\"descname\">inverse_transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.MaxMinNormalizer.inverse_transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Restore normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – normalized data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">denormalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.MaxMinNormalizer.transform\">\n<code class=\"descname\">transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.MaxMinNormalizer.transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Process input data to obtain normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – input data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">normalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.Normalizer\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">Normalizer</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.Normalizer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/abc.html#abc.ABC\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">abc.ABC</span></code></a></p>\n<p>Normalizer is the base abstract class for many normalizers such as MaxMinNormalizer and ZscoreNormalizer.You can also build your own normalizer by inheriting this class.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – Data which normalizer extracts characteristics from.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.ST_MoveSample\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">ST_MoveSample</code><span class=\"sig-paren\">(</span><em>closeness_len</em>, <em>period_len</em>, <em>trend_len</em>, <em>target_length=1</em>, <em>daily_slots=24</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.ST_MoveSample\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>This class can converts raw data into temporal features including closenss, period and trend features.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>closeness_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of closeness data history. The former consecutive <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> time slots\nof data will be used as closeness history.</li>\n<li><strong>period_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of period data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> days will be used as period history.</li>\n<li><strong>trend_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of trend data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">trend_len</span></code> weeks (every seven days) will be used as trend history.</li>\n<li><strong>target_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The numbers of steps that need prediction by one piece of history data. Have to be 1 now.\nDefault: 1 default:1.</li>\n<li><strong>daily_slots</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of records of one day. Calculated by 24 * 60 /time_fitness. default:24.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.ST_MoveSample.move_sample\">\n<code class=\"descname\">move_sample</code><span class=\"sig-paren\">(</span><em>data</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.ST_MoveSample.move_sample\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Input data to generate closeness, period, trend features and target vector y.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>data</strong> (<em>ndarray</em>) – Orginal temporal data.</td>\n</tr>\n</tbody>\n</table>\n<p>:return:closeness, period, trend and y matrices.\n:type: numpy.ndarray.</p>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.SplitData\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">SplitData</code><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.SplitData\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>This class can help split data by calling split_data and split_feed_dict method.</p>\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.preprocessor.SplitData.split_data\">\n<em class=\"property\">static </em><code class=\"descname\">split_data</code><span class=\"sig-paren\">(</span><em>data</em>, <em>ratio_list</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.SplitData.split_data\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Divide the data based on the given parameter ratio_list.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>data</strong> (<em>ndarray</em>) – Data to be split.</li>\n<li><strong>ratio_list</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – Split ratio, the <cite>data</cite> will be split according to the ratio.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"docutils\">\n<dt>:return:The elements in the returned list are the divided data, and the</dt>\n<dd>dimensions of the list are the same as ratio_list.</dd>\n</dl>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">list</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.preprocessor.SplitData.split_feed_dict\">\n<em class=\"property\">static </em><code class=\"descname\">split_feed_dict</code><span class=\"sig-paren\">(</span><em>feed_dict</em>, <em>sequence_length</em>, <em>ratio_list</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.SplitData.split_feed_dict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Divide the <cite>value</cite> data in <cite>feed_dict</cite> based on the given parameter ratio_list.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>feed_dict</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#dict\" title=\"(in Python v3.12)\"><em>dict</em></a>) – It is a dictionary composed of <cite>key-value</cite> pairs.</li>\n<li><strong>sequence_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – If the length of <cite>value</cite> in <cite>feed_dict</cite> is equal to sequence_length,\nthen this method divides the <cite>value</cite> according to the ratio without changing its <cite>key</cite>.</li>\n<li><strong>ratio_list</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – Split ratio, the data will be split according to the ratio.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\">The elements in the returned list are divided dictionaries, and the dimensions of the list are the same as ratio_list.</p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\"><p class=\"first last\">list</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.WhiteNormalizer\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">WhiteNormalizer</code><span class=\"sig-paren\">(</span><em>X</em>, <em>method='all'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.WhiteNormalizer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"#UCTB.preprocess.preprocessor.Normalizer\" title=\"UCTB.preprocess.preprocessor.Normalizer\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.preprocess.preprocessor.Normalizer</span></code></a></p>\n<p>This class’s normalization won’t do anything.</p>\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.WhiteNormalizer.inverse_transform\">\n<code class=\"descname\">inverse_transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.WhiteNormalizer.inverse_transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Restore normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – normalized data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">denormalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.WhiteNormalizer.transform\">\n<code class=\"descname\">transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.WhiteNormalizer.transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Process input data to obtain normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – input data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">normalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.ZscoreNormalizer\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">ZscoreNormalizer</code><span class=\"sig-paren\">(</span><em>X</em>, <em>method='all'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.ZscoreNormalizer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"#UCTB.preprocess.preprocessor.Normalizer\" title=\"UCTB.preprocess.preprocessor.Normalizer\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.preprocess.preprocessor.Normalizer</span></code></a></p>\n<p>This class can help normalize and denormalize data using mean and standard deviation in data by calling transform and inverse_transform method.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>X</strong> (<em>ndarray</em>) – Data which normalizer extracts characteristics from.</li>\n<li><strong>method</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Parameter to choose in which way the input data will be processed.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.ZscoreNormalizer.inverse_transform\">\n<code class=\"descname\">inverse_transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.ZscoreNormalizer.inverse_transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Restore normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – normalized data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">denormalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.ZscoreNormalizer.transform\">\n<code class=\"descname\">transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.ZscoreNormalizer.transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Process input data to obtain normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – input data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">normalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.preprocessor.chooseNormalizer\">\n<code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">chooseNormalizer</code><span class=\"sig-paren\">(</span><em>in_arg</em>, <em>X_train</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.chooseNormalizer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Choose a proper normalizer consistent with user’s input.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>in_arg</strong> (<em>str|bool|object</em>) – Function is based on it to choose different normalizer.</li>\n<li><strong>X_train</strong> (<em>numpy.ndarray</em>) – Function is based on it to initialize the normalizer.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\">The normalizer consistent with definition.</p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\"><p class=\"first last\">object.</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.preprocess.time_utils\">\n<span id=\"uctb-preprocess-time-utils-module\"></span><h2>6.2.3. UCTB.preprocess.time_utils module<a class=\"headerlink\" href=\"#module-UCTB.preprocess.time_utils\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.time_utils.is_valid_date\">\n<code class=\"descclassname\">UCTB.preprocess.time_utils.</code><code class=\"descname\">is_valid_date</code><span class=\"sig-paren\">(</span><em>date_str</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.time_utils.is_valid_date\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>date_str</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/string.html#module-string\" title=\"(in Python v3.12)\"><em>string</em></a>) – e.g. 2019-01-01</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">True if date_str is valid date,\notherwise return False.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.time_utils.is_work_day_america\">\n<code class=\"descclassname\">UCTB.preprocess.time_utils.</code><code class=\"descname\">is_work_day_america</code><span class=\"sig-paren\">(</span><em>date</em>, <em>city</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.time_utils.is_work_day_america\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>date</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/string.html#module-string\" title=\"(in Python v3.12)\"><em>string</em></a><em> or </em><a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#module-datetime\" title=\"(in Python v3.12)\"><em>datetime</em></a>) – e.g. 2019-01-01</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">True if date is not holiday in America,\notherwise return False.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.time_utils.is_work_day_china\">\n<code class=\"descclassname\">UCTB.preprocess.time_utils.</code><code class=\"descname\">is_work_day_china</code><span class=\"sig-paren\">(</span><em>date</em>, <em>city</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.time_utils.is_work_day_china\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>date</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/string.html#module-string\" title=\"(in Python v3.12)\"><em>string</em></a><em> or </em><a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#module-datetime\" title=\"(in Python v3.12)\"><em>datetime</em></a>) – e.g. 2019-01-01</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">True if date is not holiday in China,\notherwise return False.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.model_unit.html\" class=\"btn btn-neutral float-right\" title=\"6.3. UCTB.model_unit package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.dataset.html\" class=\"btn btn-neutral\" title=\"6.1. UCTB.dataset package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/UCTB.train.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.6. UCTB.train package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.7. UCTB.utils package\" href=\"UCTB.utils.html\"/>\n        <link rel=\"prev\" title=\"6.5. UCTB.evaluation package\" href=\"UCTB.evaluation.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.6. UCTB.train package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.train.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-train-package\">\n<h1>6.6. UCTB.train package<a class=\"headerlink\" href=\"#uctb-train-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.train.EarlyStopping\">\n<span id=\"uctb-train-earlystopping-module\"></span><h2>6.6.1. UCTB.train.EarlyStopping module<a class=\"headerlink\" href=\"#module-UCTB.train.EarlyStopping\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.train.EarlyStopping.</code><code class=\"descname\">EarlyStopping</code><span class=\"sig-paren\">(</span><em>patience</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Early stop if a span of newest records are not better than the current best record.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>patience</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The span of checked newest records.</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping.__record_list\">\n<code class=\"descname\">__record_list</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping.__record_list\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>list</em> – List of records.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping.__best\">\n<code class=\"descname\">__best</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping.__best\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>float</em> – The current best record.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping.__patience\">\n<code class=\"descname\">__patience</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping.__patience\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The span of checked newest records.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping.__p\">\n<code class=\"descname\">__p</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping.__p\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The number of newest records that are worse than the current best record.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping.stop\">\n<code class=\"descname\">stop</code><span class=\"sig-paren\">(</span><em>new_value</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping.stop\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Append the new record to the record list\nand check if the number of new records than are worse than the best records exceeds the limit.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>new_value</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – The new record generated by the newest model.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><code class=\"docutils literal\"><span class=\"pre\">True</span></code> if the number of new records than are worse than the best records exceeds the limit and\ntriggers early stop, otherwise <code class=\"docutils literal\"><span class=\"pre\">False</span></code>.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\">bool</a></td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.train.EarlyStopping.</code><code class=\"descname\">EarlyStoppingTTest</code><span class=\"sig-paren\">(</span><em>length</em>, <em>p_value_threshold</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Early Stop by t-test.</p>\n<p>T-test is a two-sided test for the null hypothesis that 2 independent samples\nhave identical average (expected) values. This method takes two intervals according to <code class=\"docutils literal\"><span class=\"pre\">length</span></code>\nin the record list and see if they have identical average values. If so, do early stop.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of checked interval.</li>\n<li><strong>p_value_threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – The p-value threshold to decide whether to do early stop.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest.__record_list\">\n<code class=\"descname\">__record_list</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest.__record_list\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>list</em> – List of records.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest.__best\">\n<code class=\"descname\">__best</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest.__best\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>float</em> – The current best record.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest.__test_length\">\n<code class=\"descname\">__test_length</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest.__test_length\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The length of checked interval.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest.__p_value_threshold\">\n<code class=\"descname\">__p_value_threshold</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest.__p_value_threshold\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>float</em> – The p-value threshold to decide whether to do early stop.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest.stop\">\n<code class=\"descname\">stop</code><span class=\"sig-paren\">(</span><em>new_value</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest.stop\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Take two intervals in the record list to do t-test.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>new_value</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – The new record generated by the newest model.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><code class=\"docutils literal\"><span class=\"pre\">True</span></code> if p value of t-test is smaller than threshold and\ntriggers early stop, otherwise <code class=\"docutils literal\"><span class=\"pre\">False</span></code>.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\">bool</a></td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.train.MiniBatchTrain\">\n<span id=\"uctb-train-minibatchtrain-module\"></span><h2>6.6.2. UCTB.train.MiniBatchTrain module<a class=\"headerlink\" href=\"#module-UCTB.train.MiniBatchTrain\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchFeedDict\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.train.MiniBatchTrain.</code><code class=\"descname\">MiniBatchFeedDict</code><span class=\"sig-paren\">(</span><em>feed_dict</em>, <em>sequence_length</em>, <em>batch_size</em>, <em>shuffle=True</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchFeedDict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Get small batches of data from dict for training at once.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>feed_dict</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#dict\" title=\"(in Python v3.12)\"><em>dict</em></a>) – Data dictionary consisting of key-value pairs.</li>\n<li><strong>sequence_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Only divide value in <cite>feed_dict</cite> whose length is equal\nto <cite>sequence_length</cite> into several batches.</li>\n<li><strong>batch_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of data for one training session.</li>\n<li><strong>shuffle</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – If set <cite>True</cite>, the input dict will be shuffled. default:True.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchFeedDict.get_batch\">\n<code class=\"descname\">get_batch</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.get_batch\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>For the <cite>value</cite> in <cite>feed_dict</cite> whose length is equal to sequence_length, divide the <cite>value</cite>\ninto several batches, and return one batch in order each time. For those whose length is not\nequal to sequence_length, do not change <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>value`and return it directly. There are internal variables\nto record the number of batches currently generated. When the last data is not enough to\ngenerate a batch, a batch of data from the tail is returned.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchFeedDict.restart\">\n<code class=\"descname\">restart</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.restart\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Set the variable that records the number of batches currently generated to 0, so that\nwe can call the <cite>get_batch</cite> method to generate training data in batches from scratch.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchFeedDict.shuffle\">\n<em class=\"property\">static </em><code class=\"descname\">shuffle</code><span class=\"sig-paren\">(</span><em>data</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.shuffle\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrain\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.train.MiniBatchTrain.</code><code class=\"descname\">MiniBatchTrain</code><span class=\"sig-paren\">(</span><em>X</em>, <em>Y</em>, <em>batch_size</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrain\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Get small batches of data for training at once.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>X</strong> (<em>ndarray</em>) – Input features. The first dimension of X should be sample size.</li>\n<li><strong>Y</strong> (<em>ndarray</em>) – Target values. The first dimension of Y should be sample size.</li>\n<li><strong>batch_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of data for one training session.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrain.get_batch\">\n<code class=\"descname\">get_batch</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrain.get_batch\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Returns a batch of X, Y pairs each time. There are internal variables\nto record the number of batches currently generated. When the last data\nis not enough to generate a batch, a batch of data from the tail is returned.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrain.restart\">\n<code class=\"descname\">restart</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrain.restart\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Set the variable that records the number of batches currently generated to 0, so that\nwe can call the <cite>get_batch</cite> method to generate training data in batches from scratch.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrain.shuffle\">\n<em class=\"property\">static </em><code class=\"descname\">shuffle</code><span class=\"sig-paren\">(</span><em>X</em>, <em>Y</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrain.shuffle\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Input (X, Y) pairs, shuffle and return it.</p>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.train.MiniBatchTrain.</code><code class=\"descname\">MiniBatchTrainMultiData</code><span class=\"sig-paren\">(</span><em>data</em>, <em>batch_size</em>, <em>shuffle=True</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Get small batches of data for training at once.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>data</strong> (<em>ndarray</em>) – Input data. Its first dimension should be sample size.</li>\n<li><strong>batch_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of data for one training session.</li>\n<li><strong>shuffle</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – If set <cite>True</cite>, the input data will be shuffled. default:True.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.get_batch\">\n<code class=\"descname\">get_batch</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.get_batch\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Returns a batch of data each time. There are internal variables\nto record the number of batches currently generated. When the last data\nis not enough to generate a batch, a batch of data from the tail is returned.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.restart\">\n<code class=\"descname\">restart</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.restart\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Set the variable that records the number of batches currently generated to 0, so that\nwe can call the <cite>get_batch</cite> method to generate training data in batches from scratch.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.shuffle\">\n<em class=\"property\">static </em><code class=\"descname\">shuffle</code><span class=\"sig-paren\">(</span><em>data</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.shuffle\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.utils.html\" class=\"btn btn-neutral float-right\" title=\"6.7. UCTB.utils package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.evaluation.html\" class=\"btn btn-neutral\" title=\"6.5. UCTB.evaluation package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/UCTB.utils.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.7. UCTB.utils package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"7. Benchmark\" href=\"md_file/all_results.html\"/>\n        <link rel=\"prev\" title=\"6.6. UCTB.train package\" href=\"UCTB.train.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.7. UCTB.utils package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.utils.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-utils-package\">\n<h1>6.7. UCTB.utils package<a class=\"headerlink\" href=\"#uctb-utils-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.utils.multi_threads\">\n<span id=\"uctb-utils-multi-threads-module\"></span><h2>6.7.1. UCTB.utils.multi_threads module<a class=\"headerlink\" href=\"#module-UCTB.utils.multi_threads\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.utils.multi_threads.multiple_process\">\n<code class=\"descclassname\">UCTB.utils.multi_threads.</code><code class=\"descname\">multiple_process</code><span class=\"sig-paren\">(</span><em>distribute_list</em>, <em>partition_func</em>, <em>task_func</em>, <em>n_jobs</em>, <em>reduce_func</em>, <em>parameters</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.utils.multi_threads.multiple_process\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>distribute_list</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – The “data” list to be partitioned, such as a list of files which will be\ndistributed among different tasks and each task process a part of the files.</li>\n<li><strong>partition_func</strong> (<em>function</em>) – Partition function will be used to cut the distribute_list, it should accept\nthree inputs: distribute_list, i, n_job, where i is the index of jobs (i.e. integer from 0 to n_jobs-1),\nn_jos is the number of threads; partition function should return a data_list for the job_i</li>\n<li><strong>task_func</strong> (<em>function</em>) – Task function, where the inputs are share_queue, locker, data, parameters, no return.\npls refer to the DiDi-Data processing codes for more information.</li>\n<li><strong>n_jobs</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of threads</li>\n<li><strong>reduce_func</strong> (<em>function</em>) – Reduce function which combine the outputs from all the threads into one final output.</li>\n<li><strong>parameters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – parameters send to the task function</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"md_file/all_results.html\" class=\"btn btn-neutral float-right\" title=\"7. Benchmark\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.train.html\" class=\"btn btn-neutral\" title=\"6.6. UCTB.train package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/dataset/data_loader.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.dataset.data_loader &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.dataset.data_loader</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">os</span>\n<span class=\"kn\">import</span> <span class=\"nn\">copy</span>\n<span class=\"kn\">import</span> <span class=\"nn\">datetime</span>\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">dateutil.parser</span> <span class=\"k\">import</span> <span class=\"n\">parse</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.metrics.pairwise</span> <span class=\"k\">import</span> <span class=\"n\">cosine_similarity</span>\n<span class=\"kn\">from</span> <span class=\"nn\">scipy.stats</span> <span class=\"k\">import</span> <span class=\"n\">pearsonr</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">..preprocess.time_utils</span> <span class=\"k\">import</span> <span class=\"n\">is_work_day_china</span><span class=\"p\">,</span> <span class=\"n\">is_work_day_america</span><span class=\"p\">,</span> <span class=\"n\">is_valid_date</span>\n<span class=\"kn\">from</span> <span class=\"nn\">..preprocess</span> <span class=\"k\">import</span> <span class=\"n\">MoveSample</span><span class=\"p\">,</span> <span class=\"n\">SplitData</span><span class=\"p\">,</span> <span class=\"n\">ST_MoveSample</span><span class=\"p\">,</span> <span class=\"n\">Normalizer</span>\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">GraphBuilder</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">.dataset</span> <span class=\"k\">import</span> <span class=\"n\">DataSet</span>\n\n\n<div class=\"viewcode-block\" id=\"GridTrafficLoader\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.GridTrafficLoader\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">GridTrafficLoader</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 <span class=\"n\">dataset</span><span class=\"p\">,</span>\n                 <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                 <span class=\"n\">data_range</span><span class=\"o\">=</span><span class=\"s1\">&#39;all&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">train_data_length</span><span class=\"o\">=</span><span class=\"s1\">&#39;all&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">test_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span>\n                 <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span>\n                 <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">,</span>\n                 <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span>\n                 <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                 <span class=\"n\">workday_parser</span><span class=\"o\">=</span><span class=\"n\">is_work_day_america</span><span class=\"p\">,</span>\n                 <span class=\"n\">data_dir</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span> <span class=\"o\">=</span> <span class=\"n\">DataSet</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"p\">,</span> <span class=\"n\">data_dir</span><span class=\"o\">=</span><span class=\"n\">data_dir</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span> <span class=\"o\">=</span> <span class=\"mi\">24</span> <span class=\"o\">*</span> <span class=\"mi\">60</span> <span class=\"o\">/</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">time_fitness</span>\n\n        <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">str</span> <span class=\"ow\">and</span> <span class=\"n\">data_range</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;all&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">data_range</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">grid_traffic</span><span class=\"p\">)]</span>\n        <span class=\"k\">elif</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">float</span><span class=\"p\">:</span>\n            <span class=\"n\">data_range</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">data_range</span> <span class=\"o\">*</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">grid_traffic</span><span class=\"p\">))]</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">data_range</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">),</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)]</span>\n\n        <span class=\"n\">num_time_slots</span> <span class=\"o\">=</span> <span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">grid_traffic</span><span class=\"p\">[</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"p\">:]</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># external feature</span>\n        <span class=\"n\">external_feature</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"c1\"># weather</span>\n        <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">external_feature_weather</span><span class=\"p\">)</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">external_feature</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">external_feature_weather</span><span class=\"p\">[</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]])</span>\n        <span class=\"c1\"># Weekday Feature</span>\n        <span class=\"n\">weekday_feature</span> <span class=\"o\">=</span> <span class=\"p\">[[</span><span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">workday_parser</span><span class=\"p\">(</span><span class=\"n\">parse</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">time_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n                                                <span class=\"o\">+</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">timedelta</span><span class=\"p\">(</span><span class=\"n\">hours</span><span class=\"o\">=</span><span class=\"n\">e</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">time_fitness</span> <span class=\"o\">/</span> <span class=\"mi\">60</span><span class=\"p\">))</span> <span class=\"k\">else</span> <span class=\"mi\">0</span><span class=\"p\">]</span> \\\n                           <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">num_time_slots</span> <span class=\"o\">+</span> <span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])]</span>\n        <span class=\"c1\"># Hour Feature</span>\n        <span class=\"n\">hour_feature</span> <span class=\"o\">=</span> <span class=\"p\">[[(</span><span class=\"n\">parse</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">time_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"o\">+</span>\n                          <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">timedelta</span><span class=\"p\">(</span><span class=\"n\">hours</span><span class=\"o\">=</span><span class=\"n\">e</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">time_fitness</span> <span class=\"o\">/</span> <span class=\"mi\">60</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">hour</span> <span class=\"o\">/</span> <span class=\"mf\">24.0</span><span class=\"p\">]</span>\n                        <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">num_time_slots</span> <span class=\"o\">+</span> <span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])]</span>\n\n        <span class=\"n\">external_feature</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">weekday_feature</span><span class=\"p\">)</span>\n        <span class=\"n\">external_feature</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">hour_feature</span><span class=\"p\">)</span>\n        <span class=\"n\">external_feature</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">(</span><span class=\"n\">external_feature</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">width</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">external_dim</span> <span class=\"o\">=</span> <span class=\"n\">external_feature</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">test_ratio</span> <span class=\"o\">&gt;</span> <span class=\"mi\">1</span> <span class=\"ow\">or</span> <span class=\"n\">test_ratio</span> <span class=\"o\">&lt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;test_ratio &#39;</span><span class=\"p\">)</span>\n        <span class=\"n\">train_test_ratio</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">1</span> <span class=\"o\">-</span> <span class=\"n\">test_ratio</span><span class=\"p\">,</span> <span class=\"n\">test_ratio</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span> <span class=\"o\">=</span> <span class=\"n\">SplitData</span><span class=\"o\">.</span><span class=\"n\">split_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"p\">,</span> <span class=\"n\">train_test_ratio</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_ef</span> <span class=\"o\">=</span> <span class=\"n\">SplitData</span><span class=\"o\">.</span><span class=\"n\">split_data</span><span class=\"p\">(</span><span class=\"n\">external_feature</span><span class=\"p\">,</span> <span class=\"n\">train_test_ratio</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Normalize the traffic data</span>\n        <span class=\"k\">if</span> <span class=\"n\">normalize</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">normalizer</span> <span class=\"o\">=</span> <span class=\"n\">Normalizer</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_normal</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_normal</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">train_data_length</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;all&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">train_day_length</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">train_data_length</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">train_day_length</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">):]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">train_day_length</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">):]</span>\n\n        <span class=\"c1\"># expand the test data</span>\n        <span class=\"n\">expand_start_index</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"nb\">max</span><span class=\"p\">(</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span> <span class=\"o\">*</span> <span class=\"n\">period_len</span><span class=\"p\">),</span>\n                                                        <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span> <span class=\"o\">*</span> <span class=\"mi\">7</span> <span class=\"o\">*</span> <span class=\"n\">trend_len</span><span class=\"p\">),</span> <span class=\"n\">closeness_len</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">vstack</span><span class=\"p\">([</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">[</span><span class=\"n\">expand_start_index</span><span class=\"p\">:],</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span><span class=\"p\">])</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_ef</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">vstack</span><span class=\"p\">([</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span><span class=\"p\">[</span><span class=\"n\">expand_start_index</span><span class=\"p\">:],</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_ef</span><span class=\"p\">])</span>\n\n        <span class=\"k\">assert</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">closeness_len</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">int</span> <span class=\"ow\">and</span> <span class=\"n\">closeness_len</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">0</span>\n        <span class=\"k\">assert</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">period_len</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">int</span> <span class=\"ow\">and</span> <span class=\"n\">period_len</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">0</span>\n        <span class=\"k\">assert</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">trend_len</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">int</span> <span class=\"ow\">and</span> <span class=\"n\">trend_len</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">0</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span> <span class=\"o\">=</span> <span class=\"n\">closeness_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_len</span> <span class=\"o\">=</span> <span class=\"n\">period_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_len</span> <span class=\"o\">=</span> <span class=\"n\">trend_len</span>\n\n        <span class=\"c1\"># init move sample obj</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">st_move_sample</span> <span class=\"o\">=</span> <span class=\"n\">ST_MoveSample</span><span class=\"p\">(</span><span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"n\">closeness_len</span><span class=\"p\">,</span>\n                                            <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"n\">period_len</span><span class=\"p\">,</span>\n                                            <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"n\">trend_len</span><span class=\"p\">,</span> <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">daily_slots</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_y</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">st_move_sample</span><span class=\"o\">.</span><span class=\"n\">move_sample</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_y</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">st_move_sample</span><span class=\"o\">.</span><span class=\"n\">move_sample</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"o\">.</span><span class=\"n\">squeeze</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"o\">.</span><span class=\"n\">squeeze</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"o\">.</span><span class=\"n\">squeeze</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"o\">.</span><span class=\"n\">squeeze</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"o\">.</span><span class=\"n\">squeeze</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"o\">.</span><span class=\"n\">squeeze</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_sequence_len</span> <span class=\"o\">=</span> <span class=\"nb\">max</span><span class=\"p\">((</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">)))</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_sequence_len</span> <span class=\"o\">=</span> <span class=\"nb\">max</span><span class=\"p\">((</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">)))</span>\n\n        <span class=\"c1\"># external feature</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_sequence_len</span> <span class=\"o\">-</span> <span class=\"n\">target_length</span><span class=\"p\">:</span> <span class=\"o\">-</span><span class=\"n\">target_length</span><span class=\"p\">]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_ef</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_ef</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_sequence_len</span> <span class=\"o\">-</span> <span class=\"n\">target_length</span><span class=\"p\">:</span> <span class=\"o\">-</span><span class=\"n\">target_length</span><span class=\"p\">]</span></div>\n\n\n<div class=\"viewcode-block\" id=\"NodeTrafficLoader\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;The data loader that extracts and processes data from a :obj:`DataSet` object.</span>\n\n<span class=\"sd\">    Args:</span>\n<span class=\"sd\">        dataset (str): A string containing path of the dataset pickle file or a string of name of the dataset.</span>\n<span class=\"sd\">        city (:obj:`str` or ``None``): ``None`` if dataset is file path, or a string of name of the city.</span>\n<span class=\"sd\">            Default: ``None``</span>\n<span class=\"sd\">        data_range: The range of data extracted from ``self.dataset`` to be further used. If set to ``&#39;all&#39;``, all data in</span>\n<span class=\"sd\">            ``self.dataset`` will be used. If set to a float between 0.0 and 1.0, the relative former proportion of data in</span>\n<span class=\"sd\">            ``self.dataset`` will be used. If set to a list of two integers ``[start, end]``, the data from *start* day to</span>\n<span class=\"sd\">            (*end* - 1) day of data in ``self.dataset`` will be used. Default: ``&#39;all&#39;``</span>\n<span class=\"sd\">        train_data_length: The length of train data. If set to ``&#39;all&#39;``, all data in the split train set will be used.</span>\n<span class=\"sd\">            If set to int, the latest ``train_data_length`` days of data will be used as train set. Default: ``&#39;all&#39;``</span>\n<span class=\"sd\">        test_ratio (float): The ratio of test set as data will be split into train set and test set. Default: 0.1</span>\n<span class=\"sd\">        closeness_len (int): The length of closeness data history. The former consecutive ``closeness_len`` time slots</span>\n<span class=\"sd\">            of data will be used as closeness history. Default: 6</span>\n<span class=\"sd\">        period_len (int): The length of period data history. The data of exact same time slots in former consecutive</span>\n<span class=\"sd\">            ``period_len`` days will be used as period history. Default: 7</span>\n<span class=\"sd\">        trend_len (int): The length of trend data history. The data of exact same time slots in former consecutive</span>\n<span class=\"sd\">            ``trend_len`` weeks (every seven days) will be used as trend history. Default: 4</span>\n<span class=\"sd\">        target_length (int): The numbers of steps that need prediction by one piece of history data. Have to be 1 now.</span>\n<span class=\"sd\">            Default: 1</span>\n<span class=\"sd\">        graph (str): Types of graphs used in neural methods. Graphs should be a subset of { ``&#39;Correlation&#39;``,</span>\n<span class=\"sd\">            ``&#39;Distance&#39;``, ``&#39;Interaction&#39;``, ``&#39;Line&#39;``, ``&#39;Neighbor&#39;``, ``&#39;Transfer&#39;`` } and concatenated by ``&#39;-&#39;``,</span>\n<span class=\"sd\">            and *dataset* should have data of selected graphs. Default: ``&#39;Correlation&#39;``</span>\n<span class=\"sd\">        threshold_distance (float): Used in building of distance graph. If distance of two nodes in meters is larger</span>\n<span class=\"sd\">            than ``threshold_distance``, the corresponding position of the distance graph will be 1 and otherwise</span>\n<span class=\"sd\">            0.the corresponding Default: 1000</span>\n<span class=\"sd\">        threshold_correlation (float): Used in building of correlation graph. If the Pearson correlation coefficient is</span>\n<span class=\"sd\">            larger than ``threshold_correlation``, the corresponding position of the correlation graph will be 1</span>\n<span class=\"sd\">            and otherwise 0. Default: 0</span>\n<span class=\"sd\">        threshold_interaction (float): Used in building of interatction graph. If in the latest 12 months, the number of</span>\n<span class=\"sd\">            times of interaction between two nodes is larger than ``threshold_interaction``, the corresponding position</span>\n<span class=\"sd\">            of the interaction graph will be 1 and otherwise 0. Default: 500</span>\n<span class=\"sd\">        normalize (bool): If ``True``, do min-max normalization on data. Default: ``True``</span>\n<span class=\"sd\">        workday_parser: Used to build external features to be used in neural methods. Default: ``is_work_day_america``</span>\n<span class=\"sd\">        with_lm (bool): If ``True``, data loader will build graphs according to ``graph``. Default: ``True``</span>\n<span class=\"sd\">        with_tpe (bool): If ``True``, data loader will build time position embeddings. Default: ``False``</span>\n<span class=\"sd\">        data_dir (:obj:`str` or ``None``): The dataset directory. If set to ``None``, a directory will be created. If</span>\n<span class=\"sd\">            ``dataset`` is file path, ``data_dir`` should be ``None`` too. Default: ``None``</span>\n\n<span class=\"sd\">    Attributes:</span>\n<span class=\"sd\">        dataset (DataSet): The DataSet object storing basic data.</span>\n<span class=\"sd\">        daily_slots (int): The number of time slots in one single day.</span>\n<span class=\"sd\">        station_number (int): The number of nodes.</span>\n<span class=\"sd\">        external_dim (int): The number of dimensions of external features.</span>\n<span class=\"sd\">        train_closeness (np.ndarray): The closeness history of train set data. When ``with_tpe`` is ``False``,</span>\n<span class=\"sd\">            its shape is [train_time_slot_num, ``station_number``, ``closeness_len``, 1].</span>\n<span class=\"sd\">            On the dimension of ``closeness_len``, data are arranged from earlier time slots to later time slots.</span>\n<span class=\"sd\">            If ``closeness_len`` is set to 0, train_closeness will be an empty ndarray.</span>\n<span class=\"sd\">            ``train_period``, ``train_trend``, ``test_closeness``, ``test_period``, ``test_trend`` have similar shape</span>\n<span class=\"sd\">            and construction.</span>\n<span class=\"sd\">        train_y (np.ndarray): The train set data. Its shape is [train_time_slot_num, ``station_number``, 1].</span>\n<span class=\"sd\">            ``test_y`` has similar shape and construction.</span>\n<span class=\"sd\">        LM (list): If ``with_lm`` is ``True``, the list of Laplacian matrices of graphs listed in ``graph``.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 <span class=\"n\">dataset</span><span class=\"p\">,</span>\n                 <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                 <span class=\"n\">data_range</span><span class=\"o\">=</span><span class=\"s1\">&#39;all&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">train_data_length</span><span class=\"o\">=</span><span class=\"s1\">&#39;all&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">test_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span>\n                 <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span>\n                 <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">,</span>\n                 <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span>\n                 <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">graph</span><span class=\"o\">=</span><span class=\"s1\">&#39;Correlation&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">threshold_distance</span><span class=\"o\">=</span><span class=\"mi\">1000</span><span class=\"p\">,</span>\n                 <span class=\"n\">threshold_correlation</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n                 <span class=\"n\">threshold_interaction</span><span class=\"o\">=</span><span class=\"mi\">500</span><span class=\"p\">,</span>\n                 <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                 <span class=\"n\">workday_parser</span><span class=\"o\">=</span><span class=\"n\">is_work_day_america</span><span class=\"p\">,</span>\n                 <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                 <span class=\"n\">with_tpe</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span>\n                 <span class=\"n\">data_dir</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span> <span class=\"o\">=</span> <span class=\"n\">DataSet</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"p\">,</span> <span class=\"n\">data_dir</span><span class=\"o\">=</span><span class=\"n\">data_dir</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span> <span class=\"o\">=</span> <span class=\"mi\">24</span> <span class=\"o\">*</span> <span class=\"mi\">60</span> <span class=\"o\">/</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">time_fitness</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">closeness_len</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_len</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">period_len</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_len</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">trend_len</span><span class=\"p\">)</span>\n\n        <span class=\"k\">assert</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">int</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">0</span>\n        <span class=\"k\">assert</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_len</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">int</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_len</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">0</span>\n        <span class=\"k\">assert</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_len</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">int</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_len</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">0</span>\n\n        <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">str</span> <span class=\"ow\">and</span> <span class=\"n\">data_range</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;all&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">data_range</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_traffic</span><span class=\"p\">)]</span>\n        <span class=\"k\">elif</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">float</span><span class=\"p\">:</span>\n            <span class=\"n\">data_range</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">data_range</span> <span class=\"o\">*</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_traffic</span><span class=\"p\">))]</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">data_range</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">),</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)]</span>\n\n        <span class=\"n\">num_time_slots</span> <span class=\"o\">=</span> <span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n        <span class=\"c1\"># traffic feature</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">where</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_traffic</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span> <span class=\"o\">&gt;</span> <span class=\"mi\">1</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_traffic</span><span class=\"p\">[</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span>\n            <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># external feature</span>\n        <span class=\"n\">external_feature</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"c1\"># weather</span>\n        <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">external_feature_weather</span><span class=\"p\">)</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">external_feature</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">external_feature_weather</span><span class=\"p\">[</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]])</span>\n        <span class=\"c1\"># Weekday Feature</span>\n        <span class=\"n\">weekday_feature</span> <span class=\"o\">=</span> <span class=\"p\">[[</span><span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">workday_parser</span><span class=\"p\">(</span><span class=\"n\">parse</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">time_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n                                                <span class=\"o\">+</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">timedelta</span><span class=\"p\">(</span><span class=\"n\">hours</span><span class=\"o\">=</span><span class=\"n\">e</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">time_fitness</span> <span class=\"o\">/</span> <span class=\"mi\">60</span><span class=\"p\">))</span> <span class=\"k\">else</span> <span class=\"mi\">0</span><span class=\"p\">]</span> \\\n                           <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">num_time_slots</span> <span class=\"o\">+</span> <span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])]</span>\n        <span class=\"c1\"># Hour Feature</span>\n        <span class=\"n\">hour_feature</span> <span class=\"o\">=</span> <span class=\"p\">[[(</span><span class=\"n\">parse</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">time_range</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"o\">+</span>\n                          <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">timedelta</span><span class=\"p\">(</span><span class=\"n\">hours</span><span class=\"o\">=</span><span class=\"n\">e</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">time_fitness</span> <span class=\"o\">/</span> <span class=\"mi\">60</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">hour</span> <span class=\"o\">/</span> <span class=\"mf\">24.0</span><span class=\"p\">]</span>\n                        <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">num_time_slots</span> <span class=\"o\">+</span> <span class=\"n\">data_range</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])]</span>\n\n        <span class=\"n\">external_feature</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">weekday_feature</span><span class=\"p\">)</span>\n        <span class=\"n\">external_feature</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">hour_feature</span><span class=\"p\">)</span>\n        <span class=\"n\">external_feature</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">(</span><span class=\"n\">external_feature</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">station_number</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">external_dim</span> <span class=\"o\">=</span> <span class=\"n\">external_feature</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">test_ratio</span> <span class=\"o\">&gt;</span> <span class=\"mi\">1</span> <span class=\"ow\">or</span> <span class=\"n\">test_ratio</span> <span class=\"o\">&lt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;test_ratio &#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_test_ratio</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">1</span> <span class=\"o\">-</span> <span class=\"n\">test_ratio</span><span class=\"p\">,</span> <span class=\"n\">test_ratio</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span> <span class=\"o\">=</span> <span class=\"n\">SplitData</span><span class=\"o\">.</span><span class=\"n\">split_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_test_ratio</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_ef</span> <span class=\"o\">=</span> <span class=\"n\">SplitData</span><span class=\"o\">.</span><span class=\"n\">split_data</span><span class=\"p\">(</span><span class=\"n\">external_feature</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_test_ratio</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Normalize the traffic data</span>\n        <span class=\"k\">if</span> <span class=\"n\">normalize</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">normalizer</span> <span class=\"o\">=</span> <span class=\"n\">Normalizer</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_normal</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_normal</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">train_data_length</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;all&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">train_day_length</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">train_data_length</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">train_day_length</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">):]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">train_day_length</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">):]</span>\n\n        <span class=\"c1\"># expand the test data</span>\n        <span class=\"n\">expand_start_index</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">)</span> <span class=\"o\">-</span> \\\n                             <span class=\"nb\">max</span><span class=\"p\">(</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_len</span><span class=\"p\">),</span>\n                                 <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span> <span class=\"o\">*</span> <span class=\"mi\">7</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_len</span><span class=\"p\">),</span>\n                                 <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">vstack</span><span class=\"p\">([</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">[</span><span class=\"n\">expand_start_index</span><span class=\"p\">:],</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span><span class=\"p\">])</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_ef</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">vstack</span><span class=\"p\">([</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span><span class=\"p\">[</span><span class=\"n\">expand_start_index</span><span class=\"p\">:],</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_ef</span><span class=\"p\">])</span>\n\n        <span class=\"c1\"># init move sample obj</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">st_move_sample</span> <span class=\"o\">=</span> <span class=\"n\">ST_MoveSample</span><span class=\"p\">(</span><span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span><span class=\"p\">,</span>\n                                            <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_len</span><span class=\"p\">,</span>\n                                            <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_len</span><span class=\"p\">,</span> <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">daily_slots</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_y</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">st_move_sample</span><span class=\"o\">.</span><span class=\"n\">move_sample</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">,</span> \\\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_y</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">st_move_sample</span><span class=\"o\">.</span><span class=\"n\">move_sample</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_data</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_sequence_len</span> <span class=\"o\">=</span> <span class=\"nb\">max</span><span class=\"p\">((</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">)))</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_sequence_len</span> <span class=\"o\">=</span> <span class=\"nb\">max</span><span class=\"p\">((</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">)))</span>\n\n        <span class=\"c1\"># external feature</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_ef</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_sequence_len</span> <span class=\"o\">-</span> <span class=\"n\">target_length</span><span class=\"p\">:</span> <span class=\"o\">-</span><span class=\"n\">target_length</span><span class=\"p\">]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_ef</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_ef</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_sequence_len</span> <span class=\"o\">-</span> <span class=\"n\">target_length</span><span class=\"p\">:</span> <span class=\"o\">-</span><span class=\"n\">target_length</span><span class=\"p\">]</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">with_tpe</span><span class=\"p\">:</span>\n\n            <span class=\"c1\"># Time position embedding</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_tpe</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_tpe</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">1</span> <span class=\"o\">*</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">),</span>\n                                             <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_len</span> <span class=\"o\">*</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n                                             <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_tpe</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">1</span> <span class=\"o\">*</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"mi\">7</span><span class=\"p\">,</span>\n                                            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_len</span> <span class=\"o\">*</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"mi\">7</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n                                            <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"mi\">7</span><span class=\"p\">),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness_tpe</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_tpe</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]),</span>\n                                               <span class=\"p\">[</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period_tpe</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_tpe</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]),</span>\n                                            <span class=\"p\">[</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend_tpe</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_tpe</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]),</span>\n                                           <span class=\"p\">[</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness_tpe</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_tpe</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]),</span>\n                                              <span class=\"p\">[</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period_tpe</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_tpe</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]),</span>\n                                           <span class=\"p\">[</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend_tpe</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_tpe</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]),</span>\n                                          <span class=\"p\">[</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">tpe_dim</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness_tpe</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n\n            <span class=\"c1\"># concat temporal feature with time position embedding</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness_tpe</span><span class=\"p\">,),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period_tpe</span><span class=\"p\">,),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend_tpe</span><span class=\"p\">,),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness_tpe</span><span class=\"p\">,),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period_tpe</span><span class=\"p\">,),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend_tpe</span><span class=\"p\">,),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">tpe_dim</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">with_lm</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">AM</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">threshold_distance</span> <span class=\"o\">=</span> <span class=\"n\">threshold_distance</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">threshold_correlation</span> <span class=\"o\">=</span> <span class=\"n\">threshold_correlation</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">threshold_interaction</span> <span class=\"o\">=</span> <span class=\"n\">threshold_interaction</span>\n\n            <span class=\"k\">for</span> <span class=\"n\">graph_name</span> <span class=\"ow\">in</span> <span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"s1\">&#39;-&#39;</span><span class=\"p\">):</span>\n                <span class=\"n\">AM</span><span class=\"p\">,</span> <span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">build_graph</span><span class=\"p\">(</span><span class=\"n\">graph_name</span><span class=\"p\">)</span>\n                <span class=\"k\">if</span> <span class=\"n\">AM</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n                    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">AM</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">AM</span><span class=\"p\">)</span>\n                <span class=\"k\">if</span> <span class=\"n\">LM</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n                    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">LM</span><span class=\"p\">)</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n<div class=\"viewcode-block\" id=\"NodeTrafficLoader.build_graph\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.build_graph\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">build_graph</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">graph_name</span><span class=\"p\">):</span>\n        <span class=\"n\">AM</span><span class=\"p\">,</span> <span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span>\n        <span class=\"k\">if</span> <span class=\"n\">graph_name</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;distance&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">lat_lng_list</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([[</span><span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"n\">e1</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">e1</span> <span class=\"ow\">in</span> <span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">:</span><span class=\"mi\">4</span><span class=\"p\">]]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_station_info</span><span class=\"p\">])</span>\n            <span class=\"n\">AM</span> <span class=\"o\">=</span> <span class=\"n\">GraphBuilder</span><span class=\"o\">.</span><span class=\"n\">distance_adjacent</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">],</span>\n                                                <span class=\"n\">threshold</span><span class=\"o\">=</span><span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">threshold_distance</span><span class=\"p\">))</span>\n            <span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">GraphBuilder</span><span class=\"o\">.</span><span class=\"n\">adjacent_to_laplacian</span><span class=\"p\">(</span><span class=\"n\">AM</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">graph_name</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;interaction&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">monthly_interaction</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_monthly_interaction</span><span class=\"p\">[:,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">,</span> <span class=\"p\">:][:,</span> <span class=\"p\">:,</span>\n                                  <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">]</span>\n\n            <span class=\"n\">monthly_interaction</span><span class=\"p\">,</span> <span class=\"n\">_</span> <span class=\"o\">=</span> <span class=\"n\">SplitData</span><span class=\"o\">.</span><span class=\"n\">split_data</span><span class=\"p\">(</span><span class=\"n\">monthly_interaction</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_test_ratio</span><span class=\"p\">)</span>\n\n            <span class=\"n\">annually_interaction</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">monthly_interaction</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"p\">:],</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n            <span class=\"n\">annually_interaction</span> <span class=\"o\">=</span> <span class=\"n\">annually_interaction</span> <span class=\"o\">+</span> <span class=\"n\">annually_interaction</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">()</span>\n\n            <span class=\"n\">AM</span> <span class=\"o\">=</span> <span class=\"n\">GraphBuilder</span><span class=\"o\">.</span><span class=\"n\">interaction_adjacent</span><span class=\"p\">(</span><span class=\"n\">annually_interaction</span><span class=\"p\">,</span>\n                                                   <span class=\"n\">threshold</span><span class=\"o\">=</span><span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">threshold_interaction</span><span class=\"p\">))</span>\n            <span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">GraphBuilder</span><span class=\"o\">.</span><span class=\"n\">adjacent_to_laplacian</span><span class=\"p\">(</span><span class=\"n\">AM</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">graph_name</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;correlation&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">AM</span> <span class=\"o\">=</span> <span class=\"n\">GraphBuilder</span><span class=\"o\">.</span><span class=\"n\">correlation_adjacent</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">30</span> <span class=\"o\">*</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">):],</span>\n                                                   <span class=\"n\">threshold</span><span class=\"o\">=</span><span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">threshold_correlation</span><span class=\"p\">))</span>\n            <span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">GraphBuilder</span><span class=\"o\">.</span><span class=\"n\">adjacent_to_laplacian</span><span class=\"p\">(</span><span class=\"n\">AM</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">graph_name</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;neighbor&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">GraphBuilder</span><span class=\"o\">.</span><span class=\"n\">adjacent_to_laplacian</span><span class=\"p\">(</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;contribute_data&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;graph_neighbors&#39;</span><span class=\"p\">))</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">graph_name</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;line&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">GraphBuilder</span><span class=\"o\">.</span><span class=\"n\">adjacent_to_laplacian</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;contribute_data&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;graph_lines&#39;</span><span class=\"p\">))</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">graph_name</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;transfer&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">GraphBuilder</span><span class=\"o\">.</span><span class=\"n\">adjacent_to_laplacian</span><span class=\"p\">(</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;contribute_data&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;graph_transfer&#39;</span><span class=\"p\">))</span>\n        <span class=\"k\">return</span> <span class=\"n\">AM</span><span class=\"p\">,</span> <span class=\"n\">LM</span></div></div>\n\n\n<div class=\"viewcode-block\" id=\"st_map\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.st_map\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">st_map</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">zoom</span><span class=\"o\">=</span><span class=\"mi\">11</span><span class=\"p\">,</span> <span class=\"n\">style</span><span class=\"o\">=</span><span class=\"s1\">&#39;mapbox://styles/rmetfc/ck1manozn0edb1dpmvtzle2cp&#39;</span><span class=\"p\">,</span> <span class=\"n\">build_order</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_station_info</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span> <span class=\"ow\">or</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_station_info</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;No station information found in dataset&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n    <span class=\"kn\">import</span> <span class=\"nn\">plotly</span>\n    <span class=\"kn\">from</span> <span class=\"nn\">plotly.graph_objs</span> <span class=\"k\">import</span> <span class=\"n\">Scattermapbox</span><span class=\"p\">,</span> <span class=\"n\">Layout</span>\n\n    <span class=\"n\">mapboxAccessToken</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;pk.eyJ1Ijoicm1ldGZjIiwiYSI6ImNrMW02YmwxbjAxN24zam9kNGVtMm5raWIifQ.FXKqZCxsFK-dGLLNdeRJHw&quot;</span>\n\n    <span class=\"c1\"># os.environ[&#39;MAPBOX_API_KEY&#39;] = mapboxAccessToken</span>\n\n    <span class=\"n\">lat_lng_name_list</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">:]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_station_info</span><span class=\"p\">]</span>\n    <span class=\"n\">build_order</span> <span class=\"o\">=</span> <span class=\"n\">build_order</span> <span class=\"ow\">or</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_station_info</span><span class=\"p\">)))</span>\n\n    <span class=\"n\">color</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&#39;rgb(255, 0, 0)&#39;</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"n\">build_order</span><span class=\"p\">]</span>\n\n    <span class=\"n\">lat</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">])</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_station_info</span><span class=\"p\">])[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">]</span>\n    <span class=\"n\">lng</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">])</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_station_info</span><span class=\"p\">])[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">]</span>\n    <span class=\"n\">text</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">build_order</span><span class=\"p\">))]</span>\n\n    <span class=\"n\">file_name</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">dataset</span> <span class=\"o\">+</span> <span class=\"s1\">&#39;-&#39;</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">city</span> <span class=\"o\">+</span> <span class=\"s1\">&#39;.html&#39;</span>\n\n    <span class=\"n\">bikeStations</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">Scattermapbox</span><span class=\"p\">(</span>\n        <span class=\"n\">lon</span><span class=\"o\">=</span><span class=\"n\">lng</span><span class=\"p\">,</span>\n        <span class=\"n\">lat</span><span class=\"o\">=</span><span class=\"n\">lat</span><span class=\"p\">,</span>\n        <span class=\"n\">text</span><span class=\"o\">=</span><span class=\"n\">text</span><span class=\"p\">,</span>\n        <span class=\"n\">mode</span><span class=\"o\">=</span><span class=\"s1\">&#39;markers&#39;</span><span class=\"p\">,</span>\n        <span class=\"n\">marker</span><span class=\"o\">=</span><span class=\"nb\">dict</span><span class=\"p\">(</span>\n            <span class=\"n\">size</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span>\n            <span class=\"c1\"># color=[&#39;rgb(%s, %s, %s)&#39; % (255,</span>\n            <span class=\"c1\">#                 #                             195 - e * 195 / max(build_order),</span>\n            <span class=\"c1\">#                 #                             195 - e * 195 / max(build_order)) for e in build_order],</span>\n            <span class=\"n\">color</span><span class=\"o\">=</span><span class=\"n\">color</span><span class=\"p\">,</span>\n            <span class=\"n\">opacity</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n        <span class=\"p\">))]</span>\n\n    <span class=\"n\">layout</span> <span class=\"o\">=</span> <span class=\"n\">Layout</span><span class=\"p\">(</span>\n        <span class=\"n\">title</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike Station Location &amp; The latest built stations with deeper color&#39;</span><span class=\"p\">,</span>\n        <span class=\"n\">autosize</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n        <span class=\"n\">hovermode</span><span class=\"o\">=</span><span class=\"s1\">&#39;closest&#39;</span><span class=\"p\">,</span>\n        <span class=\"n\">showlegend</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span>\n        <span class=\"n\">mapbox</span><span class=\"o\">=</span><span class=\"nb\">dict</span><span class=\"p\">(</span>\n            <span class=\"n\">accesstoken</span><span class=\"o\">=</span><span class=\"n\">mapboxAccessToken</span><span class=\"p\">,</span>\n            <span class=\"n\">bearing</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n            <span class=\"n\">center</span><span class=\"o\">=</span><span class=\"nb\">dict</span><span class=\"p\">(</span>\n                <span class=\"n\">lat</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">median</span><span class=\"p\">(</span><span class=\"n\">lat</span><span class=\"p\">),</span>\n                <span class=\"n\">lon</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">median</span><span class=\"p\">(</span><span class=\"n\">lng</span><span class=\"p\">)</span>\n            <span class=\"p\">),</span>\n            <span class=\"n\">pitch</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n            <span class=\"n\">zoom</span><span class=\"o\">=</span><span class=\"n\">zoom</span><span class=\"p\">,</span>\n            <span class=\"n\">style</span><span class=\"o\">=</span><span class=\"n\">style</span>\n        <span class=\"p\">),</span>\n    <span class=\"p\">)</span>\n\n    <span class=\"n\">fig</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"o\">=</span><span class=\"n\">bikeStations</span><span class=\"p\">,</span> <span class=\"n\">layout</span><span class=\"o\">=</span><span class=\"n\">layout</span><span class=\"p\">)</span>\n    <span class=\"n\">plotly</span><span class=\"o\">.</span><span class=\"n\">offline</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">fig</span><span class=\"p\">,</span> <span class=\"n\">filename</span><span class=\"o\">=</span><span class=\"n\">file_name</span><span class=\"p\">)</span></div>\n\n\n<div class=\"viewcode-block\" id=\"make_concat\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.make_concat\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">make_concat</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">node</span><span class=\"o\">=</span><span class=\"s1\">&#39;all&#39;</span><span class=\"p\">,</span> <span class=\"n\">is_train</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;A function to concatenate all closeness, period and trend history data to use as inputs of models.</span>\n\n<span class=\"sd\">    Args:</span>\n<span class=\"sd\">        node (int or ``&#39;all&#39;``): To specify the index of certain node. If set to ``&#39;all&#39;``, return the concatenation</span>\n<span class=\"sd\">            result of all nodes. If set to an integer, it will be the index of the selected node. Default: ``&#39;all&#39;``</span>\n<span class=\"sd\">        is_train (bool): If set to ``True``, ``train_closeness``, ``train_period``, and ``train_trend`` will be</span>\n<span class=\"sd\">            concatenated. If set to ``False``, ``test_closeness``, ``test_period``, and ``test_trend`` will be</span>\n<span class=\"sd\">            concatenated. Default: True</span>\n\n<span class=\"sd\">    Returns:</span>\n<span class=\"sd\">        np.ndarray: Function returns an ndarray with shape as</span>\n<span class=\"sd\">        [time_slot_num, ``station_number``, ``closeness_len`` + ``period_len`` + ``trend_len``, 1],</span>\n<span class=\"sd\">        and time_slot_num is the temporal length of train set data if ``is_train`` is ``True``</span>\n<span class=\"sd\">        or the temporal length of test set data if ``is_train`` is ``False``.</span>\n<span class=\"sd\">        On the second dimension, data are arranged as</span>\n<span class=\"sd\">        ``earlier closeness -&gt; later closeness -&gt; earlier period -&gt; later period -&gt; earlier trend -&gt; later trend``.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">is_train</span><span class=\"p\">:</span>\n        <span class=\"n\">length</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">)</span>\n        <span class=\"n\">closeness</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span>\n        <span class=\"n\">period</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_period</span>\n        <span class=\"n\">trend</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">train_trend</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">length</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">)</span>\n        <span class=\"n\">closeness</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span>\n        <span class=\"n\">period</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_period</span>\n        <span class=\"n\">trend</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">test_trend</span>\n    <span class=\"k\">if</span> <span class=\"n\">node</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;all&#39;</span><span class=\"p\">:</span>\n        <span class=\"n\">node</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">))</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">node</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">node</span><span class=\"p\">]</span>\n    <span class=\"n\">history</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"n\">length</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">node</span><span class=\"p\">),</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_len</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_len</span><span class=\"p\">])</span>\n    <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">node</span><span class=\"p\">)):</span>\n        <span class=\"k\">for</span> <span class=\"n\">c</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span><span class=\"p\">):</span>\n            <span class=\"n\">history</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">closeness</span><span class=\"p\">[:,</span> <span class=\"n\">node</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">],</span> <span class=\"n\">c</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n        <span class=\"k\">for</span> <span class=\"n\">p</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_len</span><span class=\"p\">):</span>\n            <span class=\"n\">history</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span> <span class=\"o\">+</span> <span class=\"n\">p</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">period</span><span class=\"p\">[:,</span> <span class=\"n\">node</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">],</span> <span class=\"n\">p</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n        <span class=\"k\">for</span> <span class=\"n\">t</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trend_len</span><span class=\"p\">):</span>\n            <span class=\"n\">history</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">period_len</span> <span class=\"o\">+</span> <span class=\"n\">t</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">trend</span><span class=\"p\">[:,</span> <span class=\"n\">node</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">],</span> <span class=\"n\">t</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n    <span class=\"n\">history</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">expand_dims</span><span class=\"p\">(</span><span class=\"n\">history</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">history</span></div>\n\n\n<div class=\"viewcode-block\" id=\"TransferDataLoader\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.TransferDataLoader\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">TransferDataLoader</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">sd_params</span><span class=\"p\">,</span> <span class=\"n\">td_params</span><span class=\"p\">,</span> <span class=\"n\">model_params</span><span class=\"p\">,</span> <span class=\"n\">td_data_length</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">td_data_length</span><span class=\"p\">:</span>\n            <span class=\"n\">td_params</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">({</span><span class=\"s1\">&#39;train_data_length&#39;</span><span class=\"p\">:</span> <span class=\"n\">td_data_length</span><span class=\"p\">})</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">sd_params</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">model_params</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">td_params</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">model_params</span><span class=\"p\">)</span>\n\n        <span class=\"n\">td_params</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">({</span><span class=\"s1\">&#39;train_data_length&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;180&#39;</span><span class=\"p\">})</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fake_td_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">td_params</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">model_params</span><span class=\"p\">)</span>\n\n<div class=\"viewcode-block\" id=\"TransferDataLoader.traffic_sim\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.TransferDataLoader.traffic_sim\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">traffic_sim</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n\n        <span class=\"k\">assert</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span> <span class=\"o\">==</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span>\n\n        <span class=\"n\">similar_record</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span>\n                       <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)):</span>\n\n            <span class=\"n\">sim</span> <span class=\"o\">=</span> <span class=\"n\">cosine_similarity</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(),</span>\n                                    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">:</span><span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">())</span>\n\n            <span class=\"n\">max_sim</span><span class=\"p\">,</span> <span class=\"n\">max_index</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">max</span><span class=\"p\">(</span><span class=\"n\">sim</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">argmax</span><span class=\"p\">(</span><span class=\"n\">sim</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">similar_record</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">similar_record</span> <span class=\"o\">=</span> <span class=\"p\">[[</span><span class=\"n\">max_sim</span><span class=\"p\">[</span><span class=\"n\">e</span><span class=\"p\">],</span> <span class=\"n\">max_index</span><span class=\"p\">[</span><span class=\"n\">e</span><span class=\"p\">],</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span>\n                                  <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">max_sim</span><span class=\"p\">))]</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"k\">for</span> <span class=\"n\">index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">similar_record</span><span class=\"p\">)):</span>\n                    <span class=\"k\">if</span> <span class=\"n\">similar_record</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">&lt;</span> <span class=\"n\">max_sim</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">]:</span>\n                        <span class=\"n\">similar_record</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">max_sim</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">],</span> <span class=\"n\">max_index</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">],</span> <span class=\"n\">i</span><span class=\"p\">,</span>\n                                                 <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">similar_record</span></div>\n\n<div class=\"viewcode-block\" id=\"TransferDataLoader.traffic_sim_fake\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.TransferDataLoader.traffic_sim_fake\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">traffic_sim_fake</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n\n        <span class=\"k\">assert</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span> <span class=\"o\">==</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fake_td_loader</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span>\n\n        <span class=\"n\">similar_record</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fake_td_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span>\n                       <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">daily_slots</span><span class=\"p\">)):</span>\n\n            <span class=\"n\">sim</span> <span class=\"o\">=</span> <span class=\"n\">cosine_similarity</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fake_td_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(),</span>\n                                    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"p\">[</span>\n                                    <span class=\"n\">i</span><span class=\"p\">:</span><span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fake_td_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">())</span>\n\n            <span class=\"n\">max_sim</span><span class=\"p\">,</span> <span class=\"n\">max_index</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">max</span><span class=\"p\">(</span><span class=\"n\">sim</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">argmax</span><span class=\"p\">(</span><span class=\"n\">sim</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">similar_record</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">similar_record</span> <span class=\"o\">=</span> <span class=\"p\">[[</span><span class=\"n\">max_sim</span><span class=\"p\">[</span><span class=\"n\">e</span><span class=\"p\">],</span> <span class=\"n\">max_index</span><span class=\"p\">[</span><span class=\"n\">e</span><span class=\"p\">],</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fake_td_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span>\n                                  <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">max_sim</span><span class=\"p\">))]</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"k\">for</span> <span class=\"n\">index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">similar_record</span><span class=\"p\">)):</span>\n                    <span class=\"k\">if</span> <span class=\"n\">similar_record</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">&lt;</span> <span class=\"n\">max_sim</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">]:</span>\n                        <span class=\"n\">similar_record</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">max_sim</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">],</span> <span class=\"n\">max_index</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">],</span> <span class=\"n\">i</span><span class=\"p\">,</span>\n                                                 <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">similar_record</span></div>\n\n<div class=\"viewcode-block\" id=\"TransferDataLoader.checkin_sim\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.TransferDataLoader.checkin_sim\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">checkin_sim</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n\n        <span class=\"kn\">from</span> <span class=\"nn\">sklearn.metrics.pairwise</span> <span class=\"k\">import</span> <span class=\"n\">cosine_similarity</span>\n\n        <span class=\"n\">td_checkin</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;ExternalFeature&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;CheckInFeature&#39;</span><span class=\"p\">]]</span>\n                              <span class=\"p\">)[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">]</span>\n        <span class=\"n\">sd_checkin</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;ExternalFeature&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;CheckInFeature&#39;</span><span class=\"p\">]]</span>\n                              <span class=\"p\">)[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">]</span>\n\n        <span class=\"n\">td_checkin</span> <span class=\"o\">=</span> <span class=\"n\">td_checkin</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">max</span><span class=\"p\">(</span><span class=\"n\">td_checkin</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">keepdims</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mf\">0.0001</span><span class=\"p\">)</span>\n        <span class=\"n\">sd_checkin</span> <span class=\"o\">=</span> <span class=\"n\">sd_checkin</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">max</span><span class=\"p\">(</span><span class=\"n\">sd_checkin</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">keepdims</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mf\">0.0001</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># cs = cosine_similarity(td_checkin, sd_checkin)</span>\n\n        <span class=\"c1\"># similar_record = [[e[np.argmax(e)], np.argmax(e), ] for e in cs]</span>\n\n        <span class=\"n\">similar_record</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"k\">for</span> <span class=\"n\">td_index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">td_checkin</span><span class=\"p\">)):</span>\n            <span class=\"n\">tmp_sim_record</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            <span class=\"k\">for</span> <span class=\"n\">sd_index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">sd_checkin</span><span class=\"p\">)):</span>\n                <span class=\"n\">r</span><span class=\"p\">,</span> <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">pearsonr</span><span class=\"p\">(</span><span class=\"n\">td_checkin</span><span class=\"p\">[</span><span class=\"n\">td_index</span><span class=\"p\">],</span> <span class=\"n\">sd_checkin</span><span class=\"p\">[</span><span class=\"n\">sd_index</span><span class=\"p\">])</span>\n                <span class=\"n\">tmp_sim_record</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">([</span><span class=\"n\">r</span><span class=\"p\">,</span> <span class=\"n\">sd_index</span><span class=\"p\">,</span>\n                                       <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">),</span>\n                                       <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">)])</span>\n            <span class=\"n\">similar_record</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"nb\">max</span><span class=\"p\">(</span><span class=\"n\">tmp_sim_record</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"o\">=</span><span class=\"k\">lambda</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"n\">x</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]))</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">similar_record</span></div>\n\n<div class=\"viewcode-block\" id=\"TransferDataLoader.checkin_sim_sd\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.TransferDataLoader.checkin_sim_sd\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">checkin_sim_sd</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n\n        <span class=\"n\">sd_checkin</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;ExternalFeature&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;CheckInFeature&#39;</span><span class=\"p\">]]</span>\n                              <span class=\"p\">)[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">]</span>\n        <span class=\"n\">sd_checkin</span> <span class=\"o\">=</span> <span class=\"n\">sd_checkin</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">max</span><span class=\"p\">(</span><span class=\"n\">sd_checkin</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">keepdims</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mf\">0.0001</span><span class=\"p\">)</span>\n\n        <span class=\"n\">cs</span> <span class=\"o\">=</span> <span class=\"n\">cosine_similarity</span><span class=\"p\">(</span><span class=\"n\">sd_checkin</span><span class=\"p\">,</span> <span class=\"n\">sd_checkin</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">eye</span><span class=\"p\">(</span><span class=\"n\">sd_checkin</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">argmax</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">cs</span><span class=\"p\">],</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">int32</span><span class=\"p\">)</span></div>\n\n<div class=\"viewcode-block\" id=\"TransferDataLoader.poi_sim\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.data_loader.TransferDataLoader.poi_sim\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">poi_sim</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n\n        <span class=\"kn\">from</span> <span class=\"nn\">sklearn.metrics.pairwise</span> <span class=\"k\">import</span> <span class=\"n\">cosine_similarity</span>\n\n        <span class=\"n\">td_checkin</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;ExternalFeature&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;CheckInFeature&#39;</span><span class=\"p\">]]</span>\n                              <span class=\"p\">)[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">td_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">]</span>\n        <span class=\"n\">sd_checkin</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;ExternalFeature&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;CheckInFeature&#39;</span><span class=\"p\">]]</span>\n                              <span class=\"p\">)[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">sd_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">]</span>\n\n        <span class=\"k\">return</span> <span class=\"p\">[[</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">argmax</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">)],</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">argmax</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">),</span> <span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">cosine_similarity</span><span class=\"p\">(</span><span class=\"n\">td_checkin</span><span class=\"p\">,</span> <span class=\"n\">sd_checkin</span><span class=\"p\">)]</span></div></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/dataset/dataset.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.dataset.dataset &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.dataset.dataset</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">os</span>\n<span class=\"kn\">import</span> <span class=\"nn\">wget</span>\n<span class=\"kn\">import</span> <span class=\"nn\">pickle</span>\n<span class=\"kn\">import</span> <span class=\"nn\">tarfile</span>\n\n\n<div class=\"viewcode-block\" id=\"DataSet\"><a class=\"viewcode-back\" href=\"../../../UCTB.dataset.html#UCTB.dataset.dataset.DataSet\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">DataSet</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;An object storing basic data from a formatted pickle file.</span>\n\n<span class=\"sd\">    See also `Build your own datasets &lt;https://di-chai.github.io/UCTB/static/tutorial.html&gt;`_.</span>\n\n<span class=\"sd\">    Args:</span>\n<span class=\"sd\">        dataset (str): A string containing path of the dataset pickle file or a string of name of the dataset.</span>\n<span class=\"sd\">        city (str or ``None``): ``None`` if dataset is file path, or a string of name of the city. Default: ``None``</span>\n<span class=\"sd\">        data_dir (str or ``None``): The dataset directory. If set to ``None``, a directory will be created.</span>\n<span class=\"sd\">            If ``dataset`` is file path, ``data_dir`` should be ``None`` too. Default: ``None``</span>\n\n<span class=\"sd\">    Attributes:</span>\n<span class=\"sd\">        data (dict): The data directly from the pickle file. ``data`` may have a ``data[&#39;contribute_data&#39;]`` dict to</span>\n<span class=\"sd\">            store supplementary data.</span>\n<span class=\"sd\">        time_range (list): From ``data[&#39;TimeRange&#39;]`` in the format of [YYYY-MM-DD, YYYY-MM-DD] indicating the time</span>\n<span class=\"sd\">            range of the data.</span>\n<span class=\"sd\">        time_fitness (int): From ``data[&#39;TimeFitness&#39;]`` indicating how many minutes is a single time slot.</span>\n<span class=\"sd\">        node_traffic (np.ndarray): Data recording the main stream data of the nodes in during the time range.</span>\n<span class=\"sd\">            From ``data[&#39;Node&#39;][&#39;TrafficNode&#39;]`` with shape as [time_slot_num, node_num].</span>\n<span class=\"sd\">        node_monthly_interaction (np.ndarray): Data recording the monthly interaction of pairs of nodes.</span>\n<span class=\"sd\">            Its shape is [month_num, node_num, node_num].It&#39;s from ``data[&#39;Node&#39;][&#39;TrafficMonthlyInteraction&#39;]``</span>\n<span class=\"sd\">            and is used to build interaction graph.</span>\n<span class=\"sd\">            Its an optional attribute and can be set as an empty list if interaction graph is not needed.</span>\n<span class=\"sd\">        node_station_info (dict): A dict storing the coordinates of nodes. It shall be formatted as {id (may be</span>\n<span class=\"sd\">            arbitrary): [id (when sorted, should be consistant with index of ``node_traffic``), latitude, longitude,</span>\n<span class=\"sd\">            other notes]}. It&#39;s from ``data[&#39;Node&#39;][&#39;StationInfo&#39;]`` and is used to build distance graph.</span>\n<span class=\"sd\">            Its an optional attribute and can be set as an empty list if distance graph is not needed.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">dataset</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">data_dir</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span> <span class=\"o\">=</span> <span class=\"n\">dataset</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">city</span> <span class=\"o\">=</span> <span class=\"n\">city</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">data_dir</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">data_dir</span> <span class=\"o\">=</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">dirname</span><span class=\"p\">(</span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">dirname</span><span class=\"p\">(</span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">abspath</span><span class=\"p\">(</span><span class=\"vm\">__file__</span><span class=\"p\">))),</span> <span class=\"s1\">&#39;data&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">isdir</span><span class=\"p\">(</span><span class=\"n\">data_dir</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"kc\">False</span><span class=\"p\">:</span>\n            <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">makedirs</span><span class=\"p\">(</span><span class=\"n\">data_dir</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">city</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">pkl_file_name</span> <span class=\"o\">=</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">data_dir</span><span class=\"p\">,</span> <span class=\"s1\">&#39;</span><span class=\"si\">{}</span><span class=\"s1\">_</span><span class=\"si\">{}</span><span class=\"s1\">.pkl&#39;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">city</span><span class=\"p\">))</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">pkl_file_name</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">isfile</span><span class=\"p\">(</span><span class=\"n\">pkl_file_name</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"kc\">False</span><span class=\"p\">:</span>\n            <span class=\"k\">try</span><span class=\"p\">:</span>\n                <span class=\"n\">tar_file_name</span> <span class=\"o\">=</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">data_dir</span><span class=\"p\">,</span> <span class=\"s1\">&#39;</span><span class=\"si\">{}</span><span class=\"s1\">_</span><span class=\"si\">{}</span><span class=\"s1\">.tar.gz&#39;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">city</span><span class=\"p\">))</span>\n                <span class=\"k\">if</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">isfile</span><span class=\"p\">(</span><span class=\"n\">tar_file_name</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"kc\">False</span><span class=\"p\">:</span>\n                    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Downloading data into&#39;</span><span class=\"p\">,</span> <span class=\"n\">data_dir</span><span class=\"p\">)</span>\n                    <span class=\"n\">wget</span><span class=\"o\">.</span><span class=\"n\">download</span><span class=\"p\">(</span><span class=\"s1\">&#39;https://github.com/Di-Chai/UCTB_Data/blob/master/</span><span class=\"si\">%s</span><span class=\"s1\">_</span><span class=\"si\">%s</span><span class=\"s1\">.tar.gz?raw=true&#39;</span> <span class=\"o\">%</span>\n                                  <span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"p\">),</span> <span class=\"n\">tar_file_name</span><span class=\"p\">)</span>\n                    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Download succeed&#39;</span><span class=\"p\">)</span>\n                <span class=\"k\">else</span><span class=\"p\">:</span>\n                    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Found&#39;</span><span class=\"p\">,</span> <span class=\"n\">tar_file_name</span><span class=\"p\">)</span>\n                <span class=\"n\">tar</span> <span class=\"o\">=</span> <span class=\"n\">tarfile</span><span class=\"o\">.</span><span class=\"n\">open</span><span class=\"p\">(</span><span class=\"n\">tar_file_name</span><span class=\"p\">,</span> <span class=\"s2\">&quot;r:gz&quot;</span><span class=\"p\">)</span>\n                <span class=\"n\">file_names</span> <span class=\"o\">=</span> <span class=\"n\">tar</span><span class=\"o\">.</span><span class=\"n\">getnames</span><span class=\"p\">()</span>\n                <span class=\"k\">for</span> <span class=\"n\">file_name</span> <span class=\"ow\">in</span> <span class=\"n\">file_names</span><span class=\"p\">:</span>\n                    <span class=\"n\">tar</span><span class=\"o\">.</span><span class=\"n\">extract</span><span class=\"p\">(</span><span class=\"n\">file_name</span><span class=\"p\">,</span> <span class=\"n\">data_dir</span><span class=\"p\">)</span>\n                <span class=\"n\">tar</span><span class=\"o\">.</span><span class=\"n\">close</span><span class=\"p\">()</span>\n                <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">remove</span><span class=\"p\">(</span><span class=\"n\">tar_file_name</span><span class=\"p\">)</span>\n            <span class=\"k\">except</span> <span class=\"ne\">Exception</span> <span class=\"k\">as</span> <span class=\"n\">e</span><span class=\"p\">:</span>\n                <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">)</span>\n                <span class=\"k\">raise</span> <span class=\"ne\">FileExistsError</span><span class=\"p\">(</span><span class=\"s1\">&#39;Download Failed&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"n\">pkl_file_name</span><span class=\"p\">,</span> <span class=\"s1\">&#39;rb&#39;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">f</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">pickle</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"n\">f</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">time_range</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;TimeRange&#39;</span><span class=\"p\">]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">time_fitness</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;TimeFitness&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">node_traffic</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficNode&#39;</span><span class=\"p\">]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">node_monthly_interaction</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficMonthlyInteraction&#39;</span><span class=\"p\">]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">node_station_info</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;StationInfo&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">grid_traffic</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Grid&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficGrid&#39;</span><span class=\"p\">]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">grid_lat_lng</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Grid&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;GridLatLng&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">external_feature_weather</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;ExternalFeature&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;Weather&#39;</span><span class=\"p\">]</span></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/evaluation/metric.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.evaluation.metric &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.evaluation.metric</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n\n<div class=\"viewcode-block\" id=\"rmse\"><a class=\"viewcode-back\" href=\"../../../UCTB.evaluation.html#UCTB.evaluation.metric.rmse\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">threshold</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n    <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span> <span class=\"ow\">in</span> <span class=\"n\">kwargs</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n        <span class=\"k\">if</span> <span class=\"n\">key</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;threshold&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">threshold</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n    <span class=\"k\">if</span> <span class=\"n\">threshold</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">prediction</span> <span class=\"o\">-</span> <span class=\"n\">target</span><span class=\"p\">)))</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">dot</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">prediction</span> <span class=\"o\">-</span> <span class=\"n\">target</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]),</span>\n                              <span class=\"n\">target</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"o\">&gt;</span> <span class=\"n\">threshold</span><span class=\"p\">)</span> <span class=\"o\">/</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">&gt;</span> <span class=\"n\">threshold</span><span class=\"p\">))[</span><span class=\"mi\">0</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">]</span></div>\n\n\n<div class=\"viewcode-block\" id=\"mape\"><a class=\"viewcode-back\" href=\"../../../UCTB.evaluation.html#UCTB.evaluation.metric.mape\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">mape</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">threshold</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n    <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span> <span class=\"ow\">in</span> <span class=\"n\">kwargs</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n        <span class=\"k\">if</span> <span class=\"n\">key</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;threshold&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">threshold</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n    <span class=\"k\">return</span> <span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">dot</span><span class=\"p\">((</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">abs</span><span class=\"p\">(</span><span class=\"n\">prediction</span> <span class=\"o\">-</span> <span class=\"n\">target</span><span class=\"p\">)</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"mi\">1</span> <span class=\"o\">-</span> <span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">&gt;</span> <span class=\"n\">threshold</span><span class=\"p\">))))</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]),</span>\n                   <span class=\"n\">target</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"o\">&gt;</span> <span class=\"n\">threshold</span><span class=\"p\">)</span> <span class=\"o\">/</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">&gt;</span> <span class=\"n\">threshold</span><span class=\"p\">))[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">]</span></div>\n\n\n<div class=\"viewcode-block\" id=\"rmse_grid\"><a class=\"viewcode-back\" href=\"../../../UCTB.evaluation.html#UCTB.evaluation.metric.rmse_grid\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">rmse_grid</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">threshold</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n    <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span> <span class=\"ow\">in</span> <span class=\"n\">kwargs</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n        <span class=\"k\">if</span> <span class=\"n\">key</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;threshold&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">threshold</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n    <span class=\"k\">if</span> <span class=\"n\">threshold</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">prediction</span> <span class=\"o\">-</span> <span class=\"n\">target</span><span class=\"p\">),</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">))</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">prediction</span> <span class=\"o\">-</span> <span class=\"n\">target</span><span class=\"p\">)</span> <span class=\"o\">*</span>\n                              <span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">&gt;</span> <span class=\"n\">threshold</span><span class=\"p\">),</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"o\">/</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">&gt;</span> <span class=\"n\">threshold</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">))</span></div>\n\n\n<div class=\"viewcode-block\" id=\"mape_grid\"><a class=\"viewcode-back\" href=\"../../../UCTB.evaluation.html#UCTB.evaluation.metric.mape_grid\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">mape_grid</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">threshold</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n    <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span> <span class=\"ow\">in</span> <span class=\"n\">kwargs</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n        <span class=\"k\">if</span> <span class=\"n\">key</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;threshold&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">threshold</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n    <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">((</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">abs</span><span class=\"p\">(</span><span class=\"n\">prediction</span> <span class=\"o\">-</span> <span class=\"n\">target</span><span class=\"p\">)</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"mi\">1</span> <span class=\"o\">-</span> <span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">&gt;</span> <span class=\"n\">threshold</span><span class=\"p\">))))</span>\n                  <span class=\"o\">*</span> <span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">&gt;</span> <span class=\"n\">threshold</span><span class=\"p\">),</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"o\">/</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">&gt;</span> <span class=\"n\">threshold</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model/ARIMA.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model.ARIMA &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model.ARIMA</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">pandas</span> <span class=\"k\">as</span> <span class=\"nn\">pd</span>\n<span class=\"kn\">import</span> <span class=\"nn\">statsmodels.api</span> <span class=\"k\">as</span> <span class=\"nn\">sm</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">warnings</span>\n<span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">filterwarnings</span><span class=\"p\">(</span><span class=\"s2\">&quot;ignore&quot;</span><span class=\"p\">)</span>\n\n\n<div class=\"viewcode-block\" id=\"ARIMA\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.ARIMA.ARIMA\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">ARIMA</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">time_sequence</span><span class=\"p\">,</span> <span class=\"n\">order</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">seasonal_order</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">),</span> <span class=\"n\">max_ar</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"n\">max_ma</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"n\">max_d</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">):</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">seasonal_order</span> <span class=\"o\">=</span> <span class=\"n\">seasonal_order</span>\n        <span class=\"n\">auto_order</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_order</span><span class=\"p\">(</span><span class=\"n\">time_sequence</span><span class=\"p\">,</span> <span class=\"n\">order</span><span class=\"p\">,</span> <span class=\"n\">max_ar</span><span class=\"o\">=</span><span class=\"n\">max_ar</span><span class=\"p\">,</span> <span class=\"n\">max_ma</span><span class=\"o\">=</span><span class=\"n\">max_ma</span><span class=\"p\">,</span> <span class=\"n\">max_d</span><span class=\"o\">=</span><span class=\"n\">max_d</span><span class=\"p\">)</span>\n        <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">sm</span><span class=\"o\">.</span><span class=\"n\">tsa</span><span class=\"o\">.</span><span class=\"n\">SARIMAX</span><span class=\"p\">(</span><span class=\"n\">time_sequence</span><span class=\"p\">,</span> <span class=\"n\">order</span><span class=\"o\">=</span><span class=\"n\">auto_order</span><span class=\"p\">,</span> <span class=\"n\">seasonal_order</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">seasonal_order</span><span class=\"p\">)</span>\n        <span class=\"n\">model_res</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">disp</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">order</span> <span class=\"o\">=</span> <span class=\"n\">auto_order</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">model_res</span> <span class=\"o\">=</span> <span class=\"n\">model_res</span>\n\n<div class=\"viewcode-block\" id=\"ARIMA.get_order\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.ARIMA.ARIMA.get_order\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">get_order</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">series</span><span class=\"p\">,</span> <span class=\"n\">order</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">max_ar</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"n\">max_ma</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">max_d</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">):</span>\n\n        <span class=\"k\">def</span> <span class=\"nf\">stationary</span><span class=\"p\">(</span><span class=\"n\">series</span><span class=\"p\">):</span>\n            <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"n\">ARIMA</span><span class=\"o\">.</span><span class=\"n\">adf_test</span><span class=\"p\">(</span><span class=\"n\">series</span><span class=\"p\">,</span> <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n            <span class=\"k\">if</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">&lt;</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"p\">][</span><span class=\"s1\">&#39;1%&#39;</span><span class=\"p\">]:</span>\n                <span class=\"k\">return</span> <span class=\"kc\">True</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"k\">return</span> <span class=\"kc\">False</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">order</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">order_i</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n            <span class=\"k\">while</span> <span class=\"ow\">not</span> <span class=\"n\">stationary</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">diff</span><span class=\"p\">(</span><span class=\"n\">series</span><span class=\"p\">,</span> <span class=\"n\">order_i</span><span class=\"p\">)):</span>\n                <span class=\"n\">order_i</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span>\n                <span class=\"k\">if</span> <span class=\"n\">order_i</span> <span class=\"o\">&gt;</span> <span class=\"n\">max_d</span><span class=\"p\">:</span>\n                    <span class=\"k\">break</span>\n            <span class=\"n\">order</span> <span class=\"o\">=</span> <span class=\"n\">sm</span><span class=\"o\">.</span><span class=\"n\">tsa</span><span class=\"o\">.</span><span class=\"n\">stattools</span><span class=\"o\">.</span><span class=\"n\">arma_order_select_ic</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">diff</span><span class=\"p\">(</span><span class=\"n\">series</span><span class=\"p\">,</span> <span class=\"n\">order_i</span><span class=\"p\">),</span>\n                                                          <span class=\"n\">max_ar</span><span class=\"o\">=</span><span class=\"n\">max_ar</span><span class=\"p\">,</span> <span class=\"n\">max_ma</span><span class=\"o\">=</span><span class=\"n\">max_ma</span><span class=\"p\">,</span>\n                                                          <span class=\"n\">ic</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;aic&#39;</span><span class=\"p\">])</span><span class=\"o\">.</span><span class=\"n\">aic_min_order</span>\n            <span class=\"n\">order</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">order</span><span class=\"p\">)</span>\n            <span class=\"n\">order</span><span class=\"o\">.</span><span class=\"n\">insert</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">order_i</span><span class=\"p\">)</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">order</span></div>\n\n<div class=\"viewcode-block\" id=\"ARIMA.adf_test\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.ARIMA.ARIMA.adf_test\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">adf_test</span><span class=\"p\">(</span><span class=\"n\">time_series</span><span class=\"p\">,</span> <span class=\"n\">max_lags</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n        <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"n\">sm</span><span class=\"o\">.</span><span class=\"n\">tsa</span><span class=\"o\">.</span><span class=\"n\">stattools</span><span class=\"o\">.</span><span class=\"n\">adfuller</span><span class=\"p\">(</span><span class=\"n\">time_series</span><span class=\"p\">,</span> <span class=\"n\">maxlag</span><span class=\"o\">=</span><span class=\"n\">max_lags</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">verbose</span><span class=\"p\">:</span>\n            <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"n\">pd</span><span class=\"o\">.</span><span class=\"n\">DataFrame</span><span class=\"p\">(</span>\n                <span class=\"n\">index</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;Test Statistic Value&#39;</span><span class=\"p\">,</span>\n                       <span class=\"s2\">&quot;p-value&quot;</span><span class=\"p\">,</span>\n                       <span class=\"s2\">&quot;Lags Used&quot;</span><span class=\"p\">,</span>\n                       <span class=\"s2\">&quot;Number of Observations Used&quot;</span><span class=\"p\">,</span>\n                       <span class=\"s2\">&quot;Critical Value(1%)&quot;</span><span class=\"p\">,</span>\n                       <span class=\"s2\">&quot;Critical Value(5%)&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Critical Value(10%)&quot;</span><span class=\"p\">],</span> <span class=\"n\">columns</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;value&#39;</span><span class=\"p\">])</span>\n            <span class=\"n\">output</span><span class=\"p\">[</span><span class=\"s1\">&#39;value&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;Test Statistic Value&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n            <span class=\"n\">output</span><span class=\"p\">[</span><span class=\"s1\">&#39;value&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;p-value&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n            <span class=\"n\">output</span><span class=\"p\">[</span><span class=\"s1\">&#39;value&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;Lags Used&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">]</span>\n            <span class=\"n\">output</span><span class=\"p\">[</span><span class=\"s1\">&#39;value&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;Number of Observations Used&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">]</span>\n            <span class=\"n\">output</span><span class=\"p\">[</span><span class=\"s1\">&#39;value&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;Critical Value(1%)&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"p\">][</span><span class=\"s1\">&#39;1%&#39;</span><span class=\"p\">]</span>\n            <span class=\"n\">output</span><span class=\"p\">[</span><span class=\"s1\">&#39;value&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;Critical Value(5%)&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"p\">][</span><span class=\"s1\">&#39;5%&#39;</span><span class=\"p\">]</span>\n            <span class=\"n\">output</span><span class=\"p\">[</span><span class=\"s1\">&#39;value&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;Critical Value(10%)&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"p\">][</span><span class=\"s1\">&#39;10%&#39;</span><span class=\"p\">]</span>\n            <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">output</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">t</span></div>\n\n<div class=\"viewcode-block\" id=\"ARIMA.predict\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.ARIMA.ARIMA.predict\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">time_sequences</span><span class=\"p\">,</span> <span class=\"n\">forecast_step</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">):</span>\n        <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">time_sequences</span><span class=\"p\">),</span> <span class=\"n\">forecast_step</span><span class=\"p\">):</span>\n            <span class=\"n\">fs</span> <span class=\"o\">=</span> <span class=\"n\">forecast_step</span> <span class=\"k\">if</span> <span class=\"p\">((</span><span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"n\">forecast_step</span><span class=\"p\">)</span> <span class=\"o\">&lt;</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">time_sequences</span><span class=\"p\">))</span> <span class=\"k\">else</span> <span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">time_sequences</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"n\">i</span><span class=\"p\">)</span>\n            <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">sm</span><span class=\"o\">.</span><span class=\"n\">tsa</span><span class=\"o\">.</span><span class=\"n\">SARIMAX</span><span class=\"p\">(</span><span class=\"n\">time_sequences</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">],</span> <span class=\"n\">order</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">order</span><span class=\"p\">,</span> <span class=\"n\">seasonal_order</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">seasonal_order</span><span class=\"p\">)</span>\n            <span class=\"n\">model_res</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">model_res</span><span class=\"o\">.</span><span class=\"n\">params</span><span class=\"p\">)</span>\n            <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">model_res</span><span class=\"o\">.</span><span class=\"n\">forecast</span><span class=\"p\">(</span><span class=\"n\">fs</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n            <span class=\"n\">result</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">p</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">result</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span></div></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model/DCRNN.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model.DCRNN &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model.DCRNN</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">BaseModel</span>\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">DCGRUCell</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.contrib</span> <span class=\"k\">import</span> <span class=\"n\">legacy_seq2seq</span>\n\n\n<div class=\"viewcode-block\" id=\"DCRNN\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.DCRNN.DCRNN\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">DCRNN</span><span class=\"p\">(</span><span class=\"n\">BaseModel</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    Args:</span>\n<span class=\"sd\">        num_nodes(int): Number of nodes in the graph, e.g. number of stations in NYC-Bike dataset.</span>\n<span class=\"sd\">        num_diffusion_matrix: Number of diffusion matrix used in model.</span>\n<span class=\"sd\">        num_rnn_units: Number of RNN units.</span>\n<span class=\"sd\">        num_rnn_layers: Number of RNN layers</span>\n<span class=\"sd\">        max_diffusion_step: Number of diffusion steps</span>\n<span class=\"sd\">        seq_len: Input sequence length</span>\n<span class=\"sd\">        use_curriculum_learning(bool): model&#39;s prediction (True) or the previous ground truth in training (False).</span>\n<span class=\"sd\">        input_dim: Dimension of the input feature</span>\n<span class=\"sd\">        output_dim: Dimension of the output feature</span>\n<span class=\"sd\">        cl_decay_steps: When use_curriculum_learning=True, cl_decay_steps is used to adjust the ratio of using ground</span>\n<span class=\"sd\">            true labels, where with more training steps, the ratio drops.</span>\n<span class=\"sd\">        target_len(int): Output sequence length.</span>\n<span class=\"sd\">        lr(float): Learning rate</span>\n<span class=\"sd\">        epsilon: epsilon in Adam</span>\n<span class=\"sd\">        optimizer_name(str): &#39;sgd&#39; or &#39;Adam&#39; optimizer</span>\n<span class=\"sd\">        code_version(str): Current version of this model code, which will be used as filename for saving the model</span>\n<span class=\"sd\">        model_dir(str): The directory to store model files. Default:&#39;model_dir&#39;.</span>\n<span class=\"sd\">        gpu_device(str): To specify the GPU to use. Default: &#39;0&#39;.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 <span class=\"n\">num_nodes</span><span class=\"p\">,</span>\n                 <span class=\"n\">num_diffusion_matrix</span><span class=\"p\">,</span>\n                 <span class=\"n\">num_rnn_units</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span>\n                 <span class=\"n\">num_rnn_layers</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">max_diffusion_step</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n                 <span class=\"n\">seq_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span>\n                 <span class=\"n\">use_curriculum_learning</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span>\n                 <span class=\"n\">input_dim</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">output_dim</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">cl_decay_steps</span><span class=\"o\">=</span><span class=\"mi\">1000</span><span class=\"p\">,</span>\n                 <span class=\"n\">target_len</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">lr</span><span class=\"o\">=</span><span class=\"mf\">1e-4</span><span class=\"p\">,</span>\n                 <span class=\"n\">epsilon</span><span class=\"o\">=</span><span class=\"mf\">1e-3</span><span class=\"p\">,</span>\n                 <span class=\"n\">optimizer_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;Adam&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"s1\">&#39;DCRNN-QuickStart&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;model_dir&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">DCRNN</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"n\">code_version</span><span class=\"p\">,</span> <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"n\">model_dir</span><span class=\"p\">,</span> <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"n\">gpu_device</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">=</span> <span class=\"n\">num_nodes</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_diffusion_matrix</span> <span class=\"o\">=</span> <span class=\"n\">num_diffusion_matrix</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_rnn_units</span> <span class=\"o\">=</span> <span class=\"n\">num_rnn_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_rnn_layers</span> <span class=\"o\">=</span> <span class=\"n\">num_rnn_layers</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_max_diffusion_step</span> <span class=\"o\">=</span> <span class=\"n\">max_diffusion_step</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_seq_len</span> <span class=\"o\">=</span> <span class=\"n\">seq_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_use_curriculum_learning</span> <span class=\"o\">=</span> <span class=\"n\">use_curriculum_learning</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span> <span class=\"o\">=</span> <span class=\"n\">input_dim</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output_dim</span> <span class=\"o\">=</span> <span class=\"n\">output_dim</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_target_len</span> <span class=\"o\">=</span> <span class=\"n\">target_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_cl_decay_steps</span> <span class=\"o\">=</span> <span class=\"n\">cl_decay_steps</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_optimizer_name</span> <span class=\"o\">=</span> <span class=\"n\">optimizer_name</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span> <span class=\"o\">=</span> <span class=\"n\">lr</span>\n        <span class=\"c1\"># self._batch_size = batch_size</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_epsilon</span> <span class=\"o\">=</span> <span class=\"n\">epsilon</span>\n\n<div class=\"viewcode-block\" id=\"DCRNN.build\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.DCRNN.DCRNN.build\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n            <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_seq_len</span><span class=\"p\">,</span>\n                                                       <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span><span class=\"p\">),</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;inputs&#39;</span><span class=\"p\">)</span>\n            <span class=\"n\">labels</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_target_len</span><span class=\"p\">,</span>\n                                                       <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output_dim</span><span class=\"p\">),</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;labels&#39;</span><span class=\"p\">)</span>\n\n            <span class=\"n\">diffusion_matrix</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_diffusion_matrix</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span>\n                                                                 <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">),</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;diffusion_matrix&#39;</span><span class=\"p\">)</span>\n\n            <span class=\"n\">batch_size</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;inputs&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">labels</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;diffusion_matrix&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">diffusion_matrix</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"n\">go_symbol</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output_dim</span><span class=\"p\">))</span>\n\n            <span class=\"n\">cell</span> <span class=\"o\">=</span> <span class=\"n\">DCGRUCell</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_rnn_units</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_diffusion_matrix</span><span class=\"p\">,</span> <span class=\"n\">diffusion_matrix</span><span class=\"p\">,</span>\n                             <span class=\"n\">max_diffusion_step</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_max_diffusion_step</span><span class=\"p\">,</span> <span class=\"n\">num_nodes</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">)</span>\n\n            <span class=\"n\">cell_with_projection</span> <span class=\"o\">=</span> <span class=\"n\">DCGRUCell</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_rnn_units</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span><span class=\"p\">,</span>\n                                             <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_diffusion_matrix</span><span class=\"p\">,</span> <span class=\"n\">diffusion_matrix</span><span class=\"p\">,</span>\n                                             <span class=\"n\">max_diffusion_step</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_max_diffusion_step</span><span class=\"p\">,</span>\n                                             <span class=\"n\">num_nodes</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span> <span class=\"n\">num_proj</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output_dim</span><span class=\"p\">)</span>\n\n            <span class=\"n\">encoding_cells</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">cell</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_rnn_layers</span>\n            <span class=\"n\">decoding_cells</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">cell</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_rnn_layers</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"n\">cell_with_projection</span><span class=\"p\">]</span>\n            <span class=\"n\">encoding_cells</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">rnn</span><span class=\"o\">.</span><span class=\"n\">MultiRNNCell</span><span class=\"p\">(</span><span class=\"n\">encoding_cells</span><span class=\"p\">,</span> <span class=\"n\">state_is_tuple</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n            <span class=\"n\">decoding_cells</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">rnn</span><span class=\"o\">.</span><span class=\"n\">MultiRNNCell</span><span class=\"p\">(</span><span class=\"n\">decoding_cells</span><span class=\"p\">,</span> <span class=\"n\">state_is_tuple</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n            <span class=\"n\">global_step</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">get_or_create_global_step</span><span class=\"p\">()</span>\n\n            <span class=\"c1\"># Outputs: (batch_size, timesteps, num_nodes, output_dim)</span>\n            <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;DCRNN_SEQ&#39;</span><span class=\"p\">):</span>\n                <span class=\"n\">inputs_unstack</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">unstack</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">batch_size</span><span class=\"p\">,</span>\n                                                                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_seq_len</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span><span class=\"p\">)),</span>\n                                            <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n                <span class=\"n\">labels_unstack</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">unstack</span><span class=\"p\">(</span>\n                    <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">labels</span><span class=\"p\">[</span><span class=\"o\">...</span><span class=\"p\">,</span> <span class=\"p\">:</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output_dim</span><span class=\"p\">],</span>\n                               <span class=\"p\">(</span><span class=\"n\">batch_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_target_len</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output_dim</span><span class=\"p\">)),</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n                <span class=\"n\">labels_unstack</span><span class=\"o\">.</span><span class=\"n\">insert</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">go_symbol</span><span class=\"p\">)</span>\n\n                <span class=\"k\">def</span> <span class=\"nf\">_compute_sampling_threshold</span><span class=\"p\">(</span><span class=\"n\">global_step</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">):</span>\n                    <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">                    Computes the sampling probability for scheduled sampling using inverse sigmoid.</span>\n<span class=\"sd\">                    global_step:</span>\n<span class=\"sd\">                    k:</span>\n<span class=\"sd\">                    :return:</span>\n<span class=\"sd\">                    &quot;&quot;&quot;</span>\n                    <span class=\"k\">return</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">cast</span><span class=\"p\">(</span><span class=\"n\">k</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"n\">k</span> <span class=\"o\">+</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">exp</span><span class=\"p\">(</span><span class=\"n\">global_step</span> <span class=\"o\">/</span> <span class=\"n\">k</span><span class=\"p\">)),</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n                <span class=\"k\">def</span> <span class=\"nf\">_loop_function_train</span><span class=\"p\">(</span><span class=\"n\">prev</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">):</span>\n                    <span class=\"c1\"># Return either the model&#39;s prediction or the previous ground truth in training.</span>\n                    <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_use_curriculum_learning</span><span class=\"p\">:</span>\n                        <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">random_uniform</span><span class=\"p\">((),</span> <span class=\"n\">minval</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">maxval</span><span class=\"o\">=</span><span class=\"mf\">1.</span><span class=\"p\">)</span>\n                        <span class=\"n\">threshold</span> <span class=\"o\">=</span> <span class=\"n\">_compute_sampling_threshold</span><span class=\"p\">(</span><span class=\"n\">global_step</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_cl_decay_steps</span><span class=\"p\">)</span>\n                        <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">cond</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">less</span><span class=\"p\">(</span><span class=\"n\">c</span><span class=\"p\">,</span> <span class=\"n\">threshold</span><span class=\"p\">),</span> <span class=\"k\">lambda</span><span class=\"p\">:</span> <span class=\"n\">labels_unstack</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">],</span> <span class=\"k\">lambda</span><span class=\"p\">:</span> <span class=\"n\">prev</span><span class=\"p\">)</span>\n                    <span class=\"k\">else</span><span class=\"p\">:</span>\n                        <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"n\">labels_unstack</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span>\n                    <span class=\"k\">return</span> <span class=\"n\">result</span>\n\n                <span class=\"k\">def</span> <span class=\"nf\">_loop_function_test</span><span class=\"p\">(</span><span class=\"n\">prev</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">):</span>\n                    <span class=\"c1\"># Return the prediction of the model in testing.</span>\n                    <span class=\"k\">return</span> <span class=\"n\">prev</span>\n\n                <span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">enc_state</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">rnn</span><span class=\"o\">.</span><span class=\"n\">static_rnn</span><span class=\"p\">(</span><span class=\"n\">encoding_cells</span><span class=\"p\">,</span> <span class=\"n\">inputs_unstack</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;train&#39;</span><span class=\"p\">,</span> <span class=\"n\">reuse</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span>\n                    <span class=\"n\">train_outputs</span><span class=\"p\">,</span> <span class=\"n\">_</span> <span class=\"o\">=</span> <span class=\"n\">legacy_seq2seq</span><span class=\"o\">.</span><span class=\"n\">rnn_decoder</span><span class=\"p\">(</span><span class=\"n\">labels_unstack</span><span class=\"p\">,</span> <span class=\"n\">enc_state</span><span class=\"p\">,</span> <span class=\"n\">decoding_cells</span><span class=\"p\">,</span>\n                                                                  <span class=\"n\">loop_function</span><span class=\"o\">=</span><span class=\"n\">_loop_function_train</span><span class=\"p\">)</span>\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;text&#39;</span><span class=\"p\">,</span> <span class=\"n\">reuse</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n                    <span class=\"n\">test_outputs</span><span class=\"p\">,</span> <span class=\"n\">_</span> <span class=\"o\">=</span> <span class=\"n\">legacy_seq2seq</span><span class=\"o\">.</span><span class=\"n\">rnn_decoder</span><span class=\"p\">(</span><span class=\"n\">labels_unstack</span><span class=\"p\">,</span> <span class=\"n\">enc_state</span><span class=\"p\">,</span> <span class=\"n\">decoding_cells</span><span class=\"p\">,</span>\n                                                                 <span class=\"n\">loop_function</span><span class=\"o\">=</span><span class=\"n\">_loop_function_test</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># Project the output to output_dim.</span>\n            <span class=\"n\">train_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">stack</span><span class=\"p\">(</span><span class=\"n\">train_outputs</span><span class=\"p\">[:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n            <span class=\"n\">test_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">stack</span><span class=\"p\">(</span><span class=\"n\">test_outputs</span><span class=\"p\">[:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># Configure optimizer</span>\n            <span class=\"n\">optimizer</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">AdamOptimizer</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span><span class=\"p\">,</span> <span class=\"n\">epsilon</span><span class=\"o\">=</span><span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_epsilon</span><span class=\"p\">))</span>\n\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_optimizer_name</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;sgd&#39;</span><span class=\"p\">:</span>\n                <span class=\"n\">optimizer</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">GradientDescentOptimizer</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span><span class=\"p\">)</span>\n\n            <span class=\"n\">loss</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">train_outputs</span> <span class=\"o\">-</span> <span class=\"n\">labels</span><span class=\"p\">[:,</span> <span class=\"p\">:,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">])))</span>\n\n            <span class=\"n\">train_op</span> <span class=\"o\">=</span> <span class=\"n\">optimizer</span><span class=\"o\">.</span><span class=\"n\">minimize</span><span class=\"p\">(</span><span class=\"n\">loss</span><span class=\"p\">)</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">test_outputs</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">loss</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">train_op</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">DCRNN</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">(</span><span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"n\">init_vars</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span></div>\n\n    <span class=\"c1\"># Define your &#39;_get_feed_dict function‘, map your input to the tf-model</span>\n    <span class=\"k\">def</span> <span class=\"nf\">_get_feed_dict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                       <span class=\"n\">inputs</span><span class=\"p\">,</span>\n                       <span class=\"n\">diffusion_matrix</span><span class=\"p\">,</span>\n                       <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,):</span>\n        <span class=\"n\">feed_dict</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n            <span class=\"s1\">&#39;inputs&#39;</span><span class=\"p\">:</span> <span class=\"n\">inputs</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;diffusion_matrix&#39;</span><span class=\"p\">:</span> <span class=\"n\">diffusion_matrix</span><span class=\"p\">,</span>\n        <span class=\"p\">}</span>\n        <span class=\"k\">if</span> <span class=\"n\">target</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">target</span>\n        <span class=\"k\">return</span> <span class=\"n\">feed_dict</span></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model/DeepST.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model.DeepST &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model.DeepST</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">os</span>\n<span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">BaseModel</span>\n\n\n<div class=\"viewcode-block\" id=\"DeepST\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.DeepST.DeepST\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">DeepST</span><span class=\"p\">(</span><span class=\"n\">BaseModel</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Deep learning-based prediction model for Spatial-Temporal data (DeepST)</span>\n\n<span class=\"sd\">    DeepST is composed of three components: 1) temporal dependent</span>\n<span class=\"sd\">    instances: describing temporal closeness, period and seasonal</span>\n<span class=\"sd\">    trend; 2) convolutional neural networks: capturing near and</span>\n<span class=\"sd\">    far spatial dependencies; 3) early and late fusions: fusing</span>\n<span class=\"sd\">    similar and different domains&#39; data.</span>\n\n<span class=\"sd\">    Reference: `DNN-Based Prediction Model for Spatial-Temporal Data (Junbo Zhang et al., 2016)</span>\n<span class=\"sd\">    &lt;https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf&gt;`_.</span>\n\n<span class=\"sd\">    Args:</span>\n<span class=\"sd\">        closeness_len (int): The length of closeness data history. The former consecutive ``closeness_len`` time slots</span>\n<span class=\"sd\">            of data will be used as closeness history.</span>\n<span class=\"sd\">        period_len (int): The length of period data history. The data of exact same time slots in former consecutive</span>\n<span class=\"sd\">            ``period_len`` days will be used as period history.</span>\n<span class=\"sd\">        trend_len (int): The length of trend data history. The data of exact same time slots in former consecutive</span>\n<span class=\"sd\">            ``trend_len`` weeks (every seven days) will be used as trend history.</span>\n<span class=\"sd\">        width (int): The width of grid data.</span>\n<span class=\"sd\">        height (int): The height of grid data.</span>\n<span class=\"sd\">        externai_dim (int): Number of dimensions of external data.</span>\n<span class=\"sd\">        kernel_size (int): Kernel size in Convolutional neural networks. Default: 3</span>\n<span class=\"sd\">        num_conv_filters (int):  the Number of filters in the convolution. Default: 64</span>\n<span class=\"sd\">        lr (float): Learning rate. Default: 1e-5</span>\n<span class=\"sd\">        code_version (str): Current version of this model code.</span>\n<span class=\"sd\">        model_dir (str): The directory to store model files. Default:&#39;model_dir&#39;</span>\n<span class=\"sd\">        gpu_device (str): To specify the GPU to use. Default: &#39;0&#39;</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 <span class=\"n\">closeness_len</span><span class=\"p\">,</span>\n                 <span class=\"n\">period_len</span><span class=\"p\">,</span>\n                 <span class=\"n\">trend_len</span><span class=\"p\">,</span>\n                 <span class=\"n\">width</span><span class=\"p\">,</span>\n                 <span class=\"n\">height</span><span class=\"p\">,</span>\n                 <span class=\"n\">external_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span>\n                 <span class=\"n\">num_conv_filters</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span>\n                 <span class=\"n\">lr</span><span class=\"o\">=</span><span class=\"mf\">1e-5</span><span class=\"p\">,</span>\n                 <span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"s1\">&#39;QuickStart-DeepST&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;model_dir&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">):</span>\n        \n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">DeepST</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"n\">code_version</span><span class=\"p\">,</span> <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"n\">model_dir</span><span class=\"p\">,</span> <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"n\">gpu_device</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span> <span class=\"o\">=</span> <span class=\"n\">width</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span> <span class=\"o\">=</span> <span class=\"n\">height</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"o\">=</span> <span class=\"n\">closeness_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"o\">=</span> <span class=\"n\">period_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"o\">=</span> <span class=\"n\">trend_len</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">=</span> <span class=\"n\">external_dim</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span> <span class=\"o\">=</span> <span class=\"n\">lr</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span> <span class=\"o\">=</span> <span class=\"n\">kernel_size</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_conv_filters</span> <span class=\"o\">=</span> <span class=\"n\">num_conv_filters</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Graph</span><span class=\"p\">()</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_GPU_DEVICE</span> <span class=\"o\">=</span> <span class=\"n\">gpu_device</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_variable_init</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_saver</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_model_dir</span> <span class=\"o\">=</span> <span class=\"n\">model_dir</span>\n\n        <span class=\"c1\"># GPU Config</span>\n        <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">environ</span><span class=\"p\">[</span><span class=\"s2\">&quot;CUDA_DEVICE_ORDER&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;PCI_BUS_ID&quot;</span>\n        <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">environ</span><span class=\"p\">[</span><span class=\"s2\">&quot;CUDA_VISIBLE_DEVICES&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_GPU_DEVICE</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_config</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">ConfigProto</span><span class=\"p\">()</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_config</span><span class=\"o\">.</span><span class=\"n\">gpu_options</span><span class=\"o\">.</span><span class=\"n\">allow_growth</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_session</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Session</span><span class=\"p\">(</span><span class=\"n\">graph</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"p\">,</span> <span class=\"n\">config</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_config</span><span class=\"p\">)</span>\n    \n<div class=\"viewcode-block\" id=\"DeepST.build\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.DeepST.DeepST.build\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n\n            <span class=\"n\">c_conf</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;c&#39;</span><span class=\"p\">)</span>\n            <span class=\"n\">p_conf</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;p&#39;</span><span class=\"p\">)</span>\n            <span class=\"n\">t_conf</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;t&#39;</span><span class=\"p\">)</span>\n\n            <span class=\"n\">target</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">)</span>\n            \n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;closeness_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">c_conf</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;period_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">p_conf</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;trend_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t_conf</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">target</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"c1\"># First convolution</span>\n            <span class=\"n\">h_c_1</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">c_conf</span><span class=\"p\">,</span> <span class=\"n\">filters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_conv_filters</span><span class=\"p\">,</span>\n                                     <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">],</span> <span class=\"n\">padding</span><span class=\"o\">=</span><span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n            <span class=\"n\">h_p_1</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">c_conf</span><span class=\"p\">,</span> <span class=\"n\">filters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_conv_filters</span><span class=\"p\">,</span>\n                                     <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">],</span> <span class=\"n\">padding</span><span class=\"o\">=</span><span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n            <span class=\"n\">h_t_1</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">c_conf</span><span class=\"p\">,</span> <span class=\"n\">filters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_conv_filters</span><span class=\"p\">,</span>\n                                     <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">],</span> <span class=\"n\">padding</span><span class=\"o\">=</span><span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># First fusion</span>\n            <span class=\"n\">h_2</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">h_c_1</span><span class=\"p\">,</span> <span class=\"n\">h_p_1</span><span class=\"p\">,</span> <span class=\"n\">h_t_1</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span>\n                                   <span class=\"n\">filters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_conv_filters</span><span class=\"p\">,</span> <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">],</span>\n                                   <span class=\"n\">padding</span><span class=\"o\">=</span><span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># Stack more convolutions</span>\n            <span class=\"n\">middle_output</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">h_2</span><span class=\"p\">,</span> <span class=\"n\">filters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_conv_filters</span><span class=\"p\">,</span>\n                                             <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">],</span>\n                                             <span class=\"n\">padding</span><span class=\"o\">=</span><span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n            <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">middle_output</span><span class=\"p\">,</span> <span class=\"n\">filters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_conv_filters</span><span class=\"p\">,</span>\n                                 <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">],</span> <span class=\"n\">padding</span><span class=\"o\">=</span><span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># external dims</span>\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">external_input</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span><span class=\"p\">])</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;external_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">external_input</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"n\">external_dense</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">dense</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">external_input</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n                <span class=\"n\">external_dense</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">external_dense</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n                <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">external_dense</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">dense</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">,</span> <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">sigmoid</span><span class=\"p\">)</span>\n\n            <span class=\"n\">loss</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">x</span> <span class=\"o\">-</span> <span class=\"n\">target</span><span class=\"p\">)),</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">)</span>\n            <span class=\"n\">train_op</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">AdamOptimizer</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">minimize</span><span class=\"p\">(</span><span class=\"n\">loss</span><span class=\"p\">)</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">x</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">loss</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">train_op</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_variable_init</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">global_variables_initializer</span><span class=\"p\">()</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_saver</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">Saver</span><span class=\"p\">()</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">DeepST</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">()</span></div>\n\n    <span class=\"c1\"># Define your &#39;_get_feed_dict function‘, map your input to the tf-model</span>\n    <span class=\"k\">def</span> <span class=\"nf\">_get_feed_dict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">closeness_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">period_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">trend_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                       <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">external_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&#39;&#39;&#39;</span>\n<span class=\"sd\">        The method to get feet dict for tensorflow model.</span>\n\n<span class=\"sd\">        Users may modify this method according to the format of input.</span>\n\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            closeness_feature (np.ndarray or ``None``): The closeness history data.</span>\n<span class=\"sd\">                If type is np.ndarray, its shape is [time_slot_num, height, width, closeness_len].</span>\n<span class=\"sd\">            period_feature (np.ndarray or ``None``): The period history data.</span>\n<span class=\"sd\">                If type is np.ndarray, its shape is [time_slot_num, height, width, period_len].</span>\n<span class=\"sd\">            trend_feature (np.ndarray or ``None``): The trend history data.</span>\n<span class=\"sd\">                If type is np.ndarray, its shape is [time_slot_num, height, width, trend_len].</span>\n<span class=\"sd\">            target (np.ndarray or ``None``): The target value data.</span>\n<span class=\"sd\">                If type is np.ndarray, its shape is [time_slot_num, height, width, 1].</span>\n<span class=\"sd\">            external_feature (np.ndarray or ``None``): The external feature data.</span>\n<span class=\"sd\">                If type is np.ndaaray, its shape is [time_slot_num, feature_num].</span>\n<span class=\"sd\">        &#39;&#39;&#39;</span>\n        <span class=\"n\">feed_dict</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n        <span class=\"k\">if</span> <span class=\"n\">target</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">target</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;external_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">external_feature</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;closeness_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">closeness_feature</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;period_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">period_feature</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;trend_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">trend_feature</span>\n        <span class=\"k\">return</span> <span class=\"n\">feed_dict</span></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model/GeoMAN.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model.GeoMAN &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model.GeoMAN</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.contrib.framework</span> <span class=\"k\">import</span> <span class=\"n\">nest</span>\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">BaseModel</span>\n\n\n<div class=\"viewcode-block\" id=\"GeoMAN\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.GeoMAN.GeoMAN\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">GeoMAN</span><span class=\"p\">(</span><span class=\"n\">BaseModel</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Multi-level Attention Networks for Geo-sensory Time Series Prediction (GeoMAN)</span>\n\n<span class=\"sd\">            GeoMAN consists of two major parts: 1) A multi-level attention mechanism (including both local and global</span>\n<span class=\"sd\">            spatial attentions in encoder and temporal attention in decoder) to model the dynamic spatio-temporal</span>\n<span class=\"sd\">            dependencies; 2) A general fusion module to incorporate the external factors from different domains (e.g.,</span>\n<span class=\"sd\">            meteorology, time of day and land use).</span>\n\n<span class=\"sd\">            Reference:</span>\n<span class=\"sd\">                `GeoMAN: Multi-level Attention Networks for Geo-sensory Time Series Prediction (Liang, Yuxuan, et al., 2018)</span>\n<span class=\"sd\">                &lt;https://www.ijcai.org/proceedings/2018/0476.pdf&gt;`_.</span>\n\n<span class=\"sd\">                `An easy implement of GeoMAN using TensorFlow (yoshall &amp; CastleLiang)</span>\n<span class=\"sd\">                &lt;https://github.com/yoshall/GeoMAN&gt;`_.</span>\n\n<span class=\"sd\">            Args:</span>\n<span class=\"sd\">                total_sensers (int): The number of total sensors used in global attention mechanism.</span>\n<span class=\"sd\">                input_dim (int): The number of dimensions of the target sensor&#39;s input.</span>\n<span class=\"sd\">                external_dim (int): The number of dimensions of the external features.</span>\n<span class=\"sd\">                output_dim (int): The number of dimensions of the target sensor&#39;s output.</span>\n<span class=\"sd\">                input_steps (int): The length of historical input data, a.k.a, input timesteps.</span>\n<span class=\"sd\">                output_steps (int): The number of steps that need prediction by one piece of history data, a.k.a, output</span>\n<span class=\"sd\">                    timesteps. Have to be 1 now.</span>\n<span class=\"sd\">                n_stacked_layers (int): The number of LSTM layers stacked in both encoder and decoder (These two are the</span>\n<span class=\"sd\">                    same). Default: 2</span>\n<span class=\"sd\">                n_encoder_hidden_units (int): The number of hidden units in each layer of encoder. Default: 128</span>\n<span class=\"sd\">                n_decoder_hidden_units (int): The number of hidden units in each layer of decoder. Default: 128</span>\n<span class=\"sd\">                dropout_rate (float): Dropout rate of LSTM layers in both encoder and decoder. Default: 0.3</span>\n<span class=\"sd\">                lr (float): Learning rate. Default: 0.001</span>\n<span class=\"sd\">                gc_rate (float): A clipping ratio for all the gradients. This operation normalizes all gradients so that</span>\n<span class=\"sd\">                    their L2-norms are less than or equal to ``gc_rate``. Default: 2.5</span>\n<span class=\"sd\">                code_version (str): Current version of this model code. Default: &#39;GeoMAN-QuickStart&#39;</span>\n<span class=\"sd\">                model_dir (str): The directory to store model files. Default:&#39;model_dir&#39;</span>\n<span class=\"sd\">                gpu_device (str): To specify the GPU to use. Default: &#39;0&#39;</span>\n<span class=\"sd\">                **kwargs (dict): Reserved for future use. May be used to pass parameters to class ``BaseModel``.</span>\n<span class=\"sd\">            &quot;&quot;&quot;</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 <span class=\"n\">total_sensers</span><span class=\"p\">,</span>\n                 <span class=\"n\">input_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">external_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">output_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">input_steps</span><span class=\"p\">,</span>\n                 <span class=\"n\">output_steps</span><span class=\"p\">,</span>\n                 <span class=\"n\">n_stacked_layers</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n                 <span class=\"n\">n_encoder_hidden_units</span><span class=\"o\">=</span><span class=\"mi\">128</span><span class=\"p\">,</span>\n                 <span class=\"n\">n_decoder_hidden_units</span><span class=\"o\">=</span><span class=\"mi\">128</span><span class=\"p\">,</span>\n                 <span class=\"n\">dropout_rate</span><span class=\"o\">=</span><span class=\"mf\">0.3</span><span class=\"p\">,</span>\n                 <span class=\"n\">lr</span><span class=\"o\">=</span><span class=\"mf\">0.001</span><span class=\"p\">,</span>\n                 <span class=\"n\">gc_rate</span><span class=\"o\">=</span><span class=\"mf\">2.5</span><span class=\"p\">,</span>\n                 <span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"s1\">&#39;GeoMAN-QuickStart&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;model_dir&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span>\n                 <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">GeoMAN</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"n\">code_version</span><span class=\"p\">,</span> <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"n\">model_dir</span><span class=\"p\">,</span> <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"n\">gpu_device</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Architecture</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_stacked_layers</span> <span class=\"o\">=</span> <span class=\"n\">n_stacked_layers</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_encoder_hidden_units</span> <span class=\"o\">=</span> <span class=\"n\">n_encoder_hidden_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_decoder_hidden_units</span> <span class=\"o\">=</span> <span class=\"n\">n_decoder_hidden_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_output_decoder</span> <span class=\"o\">=</span> <span class=\"n\">output_dim</span>  <span class=\"c1\"># n_output_decoder</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_steps_encoder</span> <span class=\"o\">=</span> <span class=\"n\">input_steps</span>  <span class=\"c1\"># encoder_steps</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_steps_decoder</span> <span class=\"o\">=</span> <span class=\"n\">output_steps</span>  <span class=\"c1\"># decoder_steps</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_input_encoder</span> <span class=\"o\">=</span> <span class=\"n\">input_dim</span>  <span class=\"c1\"># n_input_encoder</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_sensers</span> <span class=\"o\">=</span> <span class=\"n\">total_sensers</span>  <span class=\"c1\"># n_sensers</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_external_input</span> <span class=\"o\">=</span> <span class=\"n\">external_dim</span>  <span class=\"c1\"># external_dim</span>\n\n        <span class=\"c1\"># Hyperparameters</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dropout_rate</span> <span class=\"o\">=</span> <span class=\"n\">dropout_rate</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span> <span class=\"o\">=</span> <span class=\"n\">lr</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gc_rate</span> <span class=\"o\">=</span> <span class=\"n\">gc_rate</span>\n\n<div class=\"viewcode-block\" id=\"GeoMAN.build\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.GeoMAN.GeoMAN.build\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n            <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;inputs&#39;</span><span class=\"p\">):</span>\n                <span class=\"n\">local_features</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_steps_encoder</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_input_encoder</span><span class=\"p\">],</span>\n                                                <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;local_features&#39;</span><span class=\"p\">)</span>\n                <span class=\"n\">global_features</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_steps_encoder</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_sensers</span><span class=\"p\">],</span>\n                                                 <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;global_features&#39;</span><span class=\"p\">)</span>\n                <span class=\"n\">external_features</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span>\n                                                   <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_steps_decoder</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_external_input</span><span class=\"p\">],</span>\n                                                   <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;external_features&#39;</span><span class=\"p\">)</span>\n                <span class=\"n\">local_attn_states</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span>\n                                                   <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_input_encoder</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_steps_encoder</span><span class=\"p\">],</span>\n                                                   <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;local_attn_states&#39;</span><span class=\"p\">)</span>\n                <span class=\"n\">global_attn_states</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_sensers</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_input_encoder</span><span class=\"p\">,</span>\n                                                                       <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_steps_encoder</span><span class=\"p\">],</span>\n                                                    <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;global_attn_states&#39;</span><span class=\"p\">)</span>\n            <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;ground_truth&#39;</span><span class=\"p\">):</span>\n                <span class=\"n\">targets</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_steps_decoder</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_output_decoder</span><span class=\"p\">])</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;local_features&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">local_features</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;global_features&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">global_features</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;external_features&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">external_features</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;local_attn_states&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">local_attn_states</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;global_attn_states&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">global_attn_states</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;targets&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">targets</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"n\">predict_layer</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">Dense</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_output_decoder</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">kernel_initializer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">truncated_normal_initializer</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">bias_initializer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">constant_initializer</span><span class=\"p\">(</span><span class=\"mf\">0.</span><span class=\"p\">),</span>\n                                                  <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n            <span class=\"k\">def</span> <span class=\"nf\">_build_cells</span><span class=\"p\">(</span><span class=\"n\">n_hidden_units</span><span class=\"p\">):</span>\n                <span class=\"n\">cells</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n                <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_stacked_layers</span><span class=\"p\">):</span>\n                    <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"n\">f</span><span class=\"s1\">&#39;LSTM_</span><span class=\"si\">{i}</span><span class=\"s1\">&#39;</span><span class=\"p\">):</span>\n                        <span class=\"n\">cell</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">rnn</span><span class=\"o\">.</span><span class=\"n\">BasicLSTMCell</span><span class=\"p\">(</span><span class=\"n\">n_hidden_units</span><span class=\"p\">,</span>\n                                                            <span class=\"n\">forget_bias</span><span class=\"o\">=</span><span class=\"mf\">1.0</span><span class=\"p\">,</span>\n                                                            <span class=\"n\">state_is_tuple</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n                        <span class=\"n\">cell</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">rnn_cell</span><span class=\"o\">.</span><span class=\"n\">DropoutWrapper</span><span class=\"p\">(</span><span class=\"n\">cell</span><span class=\"p\">,</span> <span class=\"n\">output_keep_prob</span><span class=\"o\">=</span><span class=\"mf\">1.0</span> <span class=\"o\">-</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dropout_rate</span><span class=\"p\">)</span>\n                        <span class=\"n\">cells</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">cell</span><span class=\"p\">)</span>\n                <span class=\"n\">encoder_cell</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">rnn</span><span class=\"o\">.</span><span class=\"n\">MultiRNNCell</span><span class=\"p\">(</span><span class=\"n\">cells</span><span class=\"p\">)</span>\n                <span class=\"k\">return</span> <span class=\"n\">encoder_cell</span>\n\n            <span class=\"k\">def</span> <span class=\"nf\">_loop_function</span><span class=\"p\">(</span><span class=\"n\">prev</span><span class=\"p\">):</span>\n                <span class=\"sd\">&quot;&quot;&quot;loop function used in the decoder to generate the next input&quot;&quot;&quot;</span>\n                <span class=\"k\">return</span> <span class=\"n\">predict_layer</span><span class=\"p\">(</span><span class=\"n\">prev</span><span class=\"p\">)</span>\n\n            <span class=\"k\">def</span> <span class=\"nf\">_get_MSE_loss</span><span class=\"p\">(</span><span class=\"n\">y_true</span><span class=\"p\">,</span> <span class=\"n\">y_pred</span><span class=\"p\">):</span>\n                <span class=\"k\">return</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">pow</span><span class=\"p\">(</span><span class=\"n\">y_true</span> <span class=\"o\">-</span> <span class=\"n\">y_pred</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;MSE_loss&#39;</span><span class=\"p\">)</span>\n\n            <span class=\"k\">def</span> <span class=\"nf\">_get_l2reg_loss</span><span class=\"p\">():</span>\n                <span class=\"c1\"># l2 loss</span>\n                <span class=\"n\">reg_loss</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n                <span class=\"k\">for</span> <span class=\"n\">tf_var</span> <span class=\"ow\">in</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">trainable_variables</span><span class=\"p\">():</span>\n                    <span class=\"k\">if</span> <span class=\"s1\">&#39;kernel:&#39;</span> <span class=\"ow\">in</span> <span class=\"n\">tf_var</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"ow\">or</span> <span class=\"s1\">&#39;bias:&#39;</span> <span class=\"ow\">in</span> <span class=\"n\">tf_var</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">:</span>\n                        <span class=\"n\">reg_loss</span> <span class=\"o\">+=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">l2_loss</span><span class=\"p\">(</span><span class=\"n\">tf_var</span><span class=\"p\">))</span>\n                <span class=\"k\">return</span> <span class=\"mf\">0.001</span> <span class=\"o\">*</span> <span class=\"n\">reg_loss</span>\n\n            <span class=\"k\">def</span> <span class=\"nf\">_spatial_attention</span><span class=\"p\">(</span><span class=\"n\">local_features</span><span class=\"p\">,</span>  <span class=\"c1\"># x and X</span>\n                                   <span class=\"n\">global_features</span><span class=\"p\">,</span>\n                                   <span class=\"n\">local_attention_states</span><span class=\"p\">,</span>\n                                   <span class=\"n\">global_attention_states</span><span class=\"p\">,</span>\n                                   <span class=\"n\">encoder_cells</span><span class=\"p\">,</span>  <span class=\"c1\"># to acquire h_{t-1}, s_{t-1}</span>\n                                   <span class=\"p\">):</span>\n                <span class=\"n\">batch_size</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">local_features</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n                <span class=\"n\">output_size</span> <span class=\"o\">=</span> <span class=\"n\">encoder_cells</span><span class=\"o\">.</span><span class=\"n\">output_size</span>\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;spatial_attention&#39;</span><span class=\"p\">):</span>\n                    <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;local_spatial_attn&#39;</span><span class=\"p\">):</span>\n                        <span class=\"n\">local_attn_length</span> <span class=\"o\">=</span> <span class=\"n\">local_attention_states</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>  <span class=\"c1\"># n_input_encoder</span>\n                        <span class=\"n\">local_attn_size</span> <span class=\"o\">=</span> <span class=\"n\">local_attention_states</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>  <span class=\"c1\"># n_steps_encoder</span>\n                        <span class=\"n\">local_attn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"n\">batch_size</span><span class=\"p\">,</span> <span class=\"n\">local_attn_length</span><span class=\"p\">])</span>\n\n                        <span class=\"c1\">#  Add local features in attention</span>\n                        <span class=\"n\">x_ik</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">local_attention_states</span><span class=\"p\">,</span>\n                                          <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">local_attn_length</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">local_attn_size</span><span class=\"p\">])</span>  <span class=\"c1\"># features</span>\n                        <span class=\"n\">Ul</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s1\">&#39;spati_atten_Ul&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">local_attn_size</span><span class=\"p\">,</span> <span class=\"n\">local_attn_size</span><span class=\"p\">])</span>\n                        <span class=\"n\">Ul_x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">x_ik</span><span class=\"p\">,</span> <span class=\"n\">Ul</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># U_l * x^{i,k}</span>\n                        <span class=\"n\">vl</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s1\">&#39;spati_atten_vl&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">local_attn_size</span><span class=\"p\">])</span>  <span class=\"c1\"># v_l</span>\n\n                        <span class=\"k\">def</span> <span class=\"nf\">_local_spatial_attention</span><span class=\"p\">(</span><span class=\"n\">query</span><span class=\"p\">):</span>\n                            <span class=\"c1\"># If the query is a tuple (when stacked RNN/LSTM), flatten it</span>\n                            <span class=\"k\">if</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">query</span><span class=\"p\">,</span> <span class=\"s2\">&quot;__iter__&quot;</span><span class=\"p\">):</span>\n                                <span class=\"n\">query_list</span> <span class=\"o\">=</span> <span class=\"n\">nest</span><span class=\"o\">.</span><span class=\"n\">flatten</span><span class=\"p\">(</span><span class=\"n\">query</span><span class=\"p\">)</span>\n                                <span class=\"k\">for</span> <span class=\"n\">q</span> <span class=\"ow\">in</span> <span class=\"n\">query_list</span><span class=\"p\">:</span>\n                                    <span class=\"n\">ndims</span> <span class=\"o\">=</span> <span class=\"n\">q</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">ndims</span>\n                                    <span class=\"k\">if</span> <span class=\"n\">ndims</span><span class=\"p\">:</span>\n                                        <span class=\"k\">assert</span> <span class=\"n\">ndims</span> <span class=\"o\">==</span> <span class=\"mi\">2</span>\n                                <span class=\"n\">query</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">query_list</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n                            <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;local_spatial_attn_Wl&#39;</span><span class=\"p\">):</span>\n                                <span class=\"n\">h_s</span> <span class=\"o\">=</span> <span class=\"n\">query</span>\n                                <span class=\"n\">Wl_hs_bl</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">Dense</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">local_attn_size</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)(</span><span class=\"n\">h_s</span><span class=\"p\">)</span>\n                                <span class=\"n\">Wl_hs_bl</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">Wl_hs_bl</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">local_attn_size</span><span class=\"p\">])</span>\n                                <span class=\"n\">score</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_sum</span><span class=\"p\">(</span><span class=\"n\">vl</span> <span class=\"o\">*</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">(</span><span class=\"n\">Wl_hs_bl</span> <span class=\"o\">+</span> <span class=\"n\">Ul_x</span><span class=\"p\">),</span>\n                                                      <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">])</span>  <span class=\"c1\"># ! Ux is a 4 dims matrix, have to use reduce_sum here</span>\n                                <span class=\"n\">attention_weights</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">softmax</span><span class=\"p\">(</span><span class=\"n\">score</span><span class=\"p\">)</span>\n                            <span class=\"k\">return</span> <span class=\"n\">attention_weights</span>\n\n                    <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;global_spatial_attn&#39;</span><span class=\"p\">):</span>\n                        <span class=\"n\">global_attn_length</span> <span class=\"o\">=</span> <span class=\"n\">global_attention_states</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>  <span class=\"c1\"># n_sensor</span>\n                        <span class=\"n\">global_n_input</span> <span class=\"o\">=</span> <span class=\"n\">global_attention_states</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>  <span class=\"c1\"># n_input_dim</span>\n                        <span class=\"n\">global_attn_size</span> <span class=\"o\">=</span> <span class=\"n\">global_attention_states</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">3</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>  <span class=\"c1\"># n_input_dim</span>\n                        <span class=\"n\">global_attn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"n\">batch_size</span><span class=\"p\">,</span> <span class=\"n\">global_attn_length</span><span class=\"p\">])</span>\n\n                        <span class=\"c1\"># Add global features in attention</span>\n                        <span class=\"n\">Xl</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">global_attention_states</span><span class=\"p\">,</span>\n                                        <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">global_attn_length</span><span class=\"p\">,</span> <span class=\"n\">global_n_input</span><span class=\"p\">,</span> <span class=\"n\">global_attn_size</span><span class=\"p\">])</span>\n                        <span class=\"n\">Wg_ug</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s1\">&#39;spati_atten_Wg_ug&#39;</span><span class=\"p\">,</span>\n                                                <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">global_n_input</span><span class=\"p\">,</span> <span class=\"n\">global_attn_size</span><span class=\"p\">,</span> <span class=\"n\">global_attn_size</span><span class=\"p\">])</span>\n                        <span class=\"n\">Wg_Xl_ug</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">Xl</span><span class=\"p\">,</span> <span class=\"n\">Wg_ug</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">)</span>\n                        <span class=\"n\">vg</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s1\">&#39;spati_atten_vg&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">local_attn_size</span><span class=\"p\">])</span>\n\n                        <span class=\"c1\"># TODO: add U_g * y^l here, where y^l is the first column of local inputs.</span>\n\n                        <span class=\"k\">def</span> <span class=\"nf\">_global_spatial_attention</span><span class=\"p\">(</span><span class=\"n\">query</span><span class=\"p\">):</span>\n                            <span class=\"k\">if</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">query</span><span class=\"p\">,</span> <span class=\"s2\">&quot;__iter__&quot;</span><span class=\"p\">):</span>\n                                <span class=\"n\">query_list</span> <span class=\"o\">=</span> <span class=\"n\">nest</span><span class=\"o\">.</span><span class=\"n\">flatten</span><span class=\"p\">(</span><span class=\"n\">query</span><span class=\"p\">)</span>\n                                <span class=\"k\">for</span> <span class=\"n\">q</span> <span class=\"ow\">in</span> <span class=\"n\">query_list</span><span class=\"p\">:</span>  <span class=\"c1\"># Check that ndims == 2 if specified.</span>\n                                    <span class=\"n\">ndims</span> <span class=\"o\">=</span> <span class=\"n\">q</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">ndims</span>\n                                    <span class=\"k\">if</span> <span class=\"n\">ndims</span><span class=\"p\">:</span>\n                                        <span class=\"k\">assert</span> <span class=\"n\">ndims</span> <span class=\"o\">==</span> <span class=\"mi\">2</span>\n                                <span class=\"n\">query</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">query_list</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n                            <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;global_spatial_attn_Wl&#39;</span><span class=\"p\">):</span>\n                                <span class=\"n\">h_s</span> <span class=\"o\">=</span> <span class=\"n\">query</span>\n                                <span class=\"n\">Wg_hs_bg</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">Dense</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">global_attn_size</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)(</span><span class=\"n\">h_s</span><span class=\"p\">)</span>\n                                <span class=\"n\">Wg_hs_bg</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">Wg_hs_bg</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">global_attn_size</span><span class=\"p\">])</span>\n                                <span class=\"n\">score</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_sum</span><span class=\"p\">(</span><span class=\"n\">vg</span> <span class=\"o\">*</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">(</span><span class=\"n\">Wg_hs_bg</span> <span class=\"o\">+</span> <span class=\"n\">Wg_Xl_ug</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">])</span>\n                                <span class=\"n\">attention_weights</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">softmax</span><span class=\"p\">(</span><span class=\"n\">score</span><span class=\"p\">)</span>\n                                <span class=\"c1\"># Sometimes it&#39;s not easy to find a measurement to denote similarity between sensors,</span>\n                                <span class=\"c1\"># here we omit such prior knowledge in eq.[4].</span>\n                                <span class=\"c1\"># You can use &quot;a = nn_ops.softmax((1-lambda)*s + lambda*sim)&quot; to encode similarity info,</span>\n                                <span class=\"c1\"># where:</span>\n                                <span class=\"c1\">#     sim: a vector with length n_sensors, describing the sim between the target sensor and the others</span>\n                                <span class=\"c1\">#     lambda: a trade-off.</span>\n                                <span class=\"c1\"># attention_weights = tf.softmax((1-self.sm_rate)*score+self.sm_rate*self.similarity_graph)</span>\n                            <span class=\"k\">return</span> <span class=\"n\">attention_weights</span>\n\n                    <span class=\"c1\"># Init</span>\n                    <span class=\"n\">zeros</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"n\">batch_size</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"p\">])</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)]</span>\n                    <span class=\"n\">initial_state</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">zeros</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">encoder_cells</span><span class=\"o\">.</span><span class=\"n\">_cells</span><span class=\"p\">))]</span>\n                    <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"n\">initial_state</span>\n\n                    <span class=\"c1\"># For each timestep</span>\n                    <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n                    <span class=\"n\">attn_weights</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n                    <span class=\"k\">for</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">local_input</span><span class=\"p\">,</span> <span class=\"n\">global_input</span><span class=\"p\">)</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"n\">local_features</span><span class=\"p\">,</span> <span class=\"n\">global_features</span><span class=\"p\">)):</span>\n                        <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable_scope</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">reuse_variables</span><span class=\"p\">()</span>\n\n                        <span class=\"n\">local_context_vector</span> <span class=\"o\">=</span> <span class=\"n\">local_attn</span> <span class=\"o\">*</span> <span class=\"n\">local_input</span>\n                        <span class=\"n\">global_context_vector</span> <span class=\"o\">=</span> <span class=\"n\">global_attn</span> <span class=\"o\">*</span> <span class=\"n\">global_input</span>\n                        <span class=\"n\">x_t</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">local_context_vector</span><span class=\"p\">,</span> <span class=\"n\">global_context_vector</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n                        <span class=\"n\">encoder_output</span><span class=\"p\">,</span> <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"n\">encoder_cells</span><span class=\"p\">(</span><span class=\"n\">x_t</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">)</span>  <span class=\"c1\"># Update states</span>\n\n                        <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;local_spatial_attn&#39;</span><span class=\"p\">):</span>\n                            <span class=\"n\">local_attn</span> <span class=\"o\">=</span> <span class=\"n\">_local_spatial_attention</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">)</span>\n                        <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;global_spatial_attn&#39;</span><span class=\"p\">):</span>\n                            <span class=\"n\">global_attn</span> <span class=\"o\">=</span> <span class=\"n\">_global_spatial_attention</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">)</span>\n                        <span class=\"n\">attn_weights</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">((</span><span class=\"n\">local_attn</span><span class=\"p\">,</span> <span class=\"n\">global_attn</span><span class=\"p\">))</span>\n                        <span class=\"n\">outputs</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">encoder_output</span><span class=\"p\">)</span>\n\n                <span class=\"k\">return</span> <span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">attn_weights</span>\n\n            <span class=\"k\">def</span> <span class=\"nf\">_temporal_attention</span><span class=\"p\">(</span><span class=\"n\">decoder_inputs</span><span class=\"p\">,</span>\n                                    <span class=\"n\">external_features</span><span class=\"p\">,</span>\n                                    <span class=\"n\">inital_states</span><span class=\"p\">,</span>  <span class=\"c1\"># the first time, the output of encoder</span>\n                                    <span class=\"n\">attention_states</span><span class=\"p\">,</span>  <span class=\"c1\"># h_o</span>\n                                    <span class=\"n\">decoder_cells</span><span class=\"p\">):</span>\n                <span class=\"n\">batch_size</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">decoder_inputs</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n                <span class=\"n\">output_size</span> <span class=\"o\">=</span> <span class=\"n\">decoder_cells</span><span class=\"o\">.</span><span class=\"n\">output_size</span>\n                <span class=\"n\">input_size</span> <span class=\"o\">=</span> <span class=\"n\">decoder_inputs</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">with_rank</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)[</span><span class=\"mi\">1</span><span class=\"p\">]</span>  <span class=\"c1\"># ?</span>\n                <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"n\">inital_states</span>\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;temperal_attention&#39;</span><span class=\"p\">):</span>\n                    <span class=\"n\">attn_length</span> <span class=\"o\">=</span> <span class=\"n\">attention_states</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n                    <span class=\"n\">attn_size</span> <span class=\"o\">=</span> <span class=\"n\">attention_states</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n\n                    <span class=\"n\">h_o</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">attention_states</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">attn_length</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">attn_size</span><span class=\"p\">])</span>\n                    <span class=\"n\">W_d</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s1\">&#39;temperal_attn_Wd&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">attn_size</span><span class=\"p\">,</span> <span class=\"n\">attn_size</span><span class=\"p\">])</span>\n                    <span class=\"n\">W_h</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">h_o</span><span class=\"p\">,</span> <span class=\"n\">W_d</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">)</span>\n                    <span class=\"n\">v_d</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s1\">&#39;temperal_attn_vd&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">attn_size</span><span class=\"p\">])</span>\n\n                    <span class=\"k\">def</span> <span class=\"nf\">_attention</span><span class=\"p\">(</span><span class=\"n\">query</span><span class=\"p\">):</span>\n                        <span class=\"k\">if</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">query</span><span class=\"p\">,</span> <span class=\"s2\">&quot;__iter__&quot;</span><span class=\"p\">):</span>\n                            <span class=\"n\">query_list</span> <span class=\"o\">=</span> <span class=\"n\">nest</span><span class=\"o\">.</span><span class=\"n\">flatten</span><span class=\"p\">(</span><span class=\"n\">query</span><span class=\"p\">)</span>\n                            <span class=\"k\">for</span> <span class=\"n\">q</span> <span class=\"ow\">in</span> <span class=\"n\">query_list</span><span class=\"p\">:</span>  <span class=\"c1\"># Check that ndims == 2 if specified.</span>\n                                <span class=\"n\">ndims</span> <span class=\"o\">=</span> <span class=\"n\">q</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">ndims</span>\n                                <span class=\"k\">if</span> <span class=\"n\">ndims</span><span class=\"p\">:</span>\n                                    <span class=\"k\">assert</span> <span class=\"n\">ndims</span> <span class=\"o\">==</span> <span class=\"mi\">2</span>\n                            <span class=\"n\">query</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">query_list</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n                        <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;attention&#39;</span><span class=\"p\">):</span>\n                            <span class=\"n\">d_s</span> <span class=\"o\">=</span> <span class=\"n\">query</span>\n                            <span class=\"n\">W_ds_b</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">Dense</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">attn_size</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)(</span><span class=\"n\">d_s</span><span class=\"p\">)</span>\n                            <span class=\"n\">W_ds_b</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">W_ds_b</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">attn_size</span><span class=\"p\">])</span>\n                            <span class=\"n\">score</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_sum</span><span class=\"p\">(</span><span class=\"n\">v_d</span> <span class=\"o\">*</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">(</span><span class=\"n\">W_ds_b</span> <span class=\"o\">+</span> <span class=\"n\">W_h</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">])</span>\n                            <span class=\"n\">attention_weights</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">softmax</span><span class=\"p\">(</span><span class=\"n\">score</span><span class=\"p\">)</span>\n                            <span class=\"n\">context_vector</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_sum</span><span class=\"p\">(</span>\n                                <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">attention_weights</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">attn_length</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"o\">*</span> <span class=\"n\">h_o</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">])</span>\n                            <span class=\"n\">context_vector</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">context_vector</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">attn_size</span><span class=\"p\">])</span>\n                        <span class=\"k\">return</span> <span class=\"n\">context_vector</span>\n\n                    <span class=\"c1\"># Init</span>\n                    <span class=\"n\">inital_attn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"n\">batch_size</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"p\">])</span>\n                    <span class=\"n\">attn</span> <span class=\"o\">=</span> <span class=\"n\">inital_attn</span>\n                    <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n                    <span class=\"n\">prev_decoder_output</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>  <span class=\"c1\"># d_{t-1}</span>\n                    <span class=\"k\">for</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">decoder_input</span><span class=\"p\">,</span> <span class=\"n\">external_input</span><span class=\"p\">)</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"n\">decoder_inputs</span><span class=\"p\">,</span> <span class=\"n\">external_features</span><span class=\"p\">)):</span>\n                        <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable_scope</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">reuse_variables</span><span class=\"p\">()</span>\n                        <span class=\"k\">if</span> <span class=\"n\">prev_decoder_output</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"n\">_loop_function</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n                            <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;loop_function&#39;</span><span class=\"p\">,</span> <span class=\"n\">reuse</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n                                <span class=\"n\">decoder_input</span> <span class=\"o\">=</span> <span class=\"n\">_loop_function</span><span class=\"p\">(</span><span class=\"n\">prev_decoder_output</span><span class=\"p\">)</span>\n                        <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">decoder_input</span><span class=\"p\">,</span> <span class=\"n\">external_input</span><span class=\"p\">,</span> <span class=\"n\">attn</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n                        <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">Dense</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">input_size</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)(</span><span class=\"n\">x</span><span class=\"p\">)</span>\n                        <span class=\"n\">decoder_output</span><span class=\"p\">,</span> <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"n\">decoder_cells</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">)</span>\n                        <span class=\"c1\"># Update attention weights</span>\n                        <span class=\"n\">attn</span> <span class=\"o\">=</span> <span class=\"n\">_attention</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">)</span>\n                        <span class=\"c1\"># Attention output projection</span>\n                        <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s2\">&quot;attn_output_projection&quot;</span><span class=\"p\">):</span>\n                            <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">decoder_output</span><span class=\"p\">,</span> <span class=\"n\">attn</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n                            <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">Dense</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"n\">output_size</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)(</span><span class=\"n\">x</span><span class=\"p\">)</span>\n                        <span class=\"n\">outputs</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">output</span><span class=\"p\">)</span>\n                        <span class=\"n\">prev_decoder_output</span> <span class=\"o\">=</span> <span class=\"n\">output</span>\n                <span class=\"k\">return</span> <span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">state</span>\n\n            <span class=\"c1\"># Handle data</span>\n            <span class=\"n\">local_features</span><span class=\"p\">,</span> <span class=\"n\">global_features</span><span class=\"p\">,</span> <span class=\"n\">external_features</span><span class=\"p\">,</span> <span class=\"n\">targets</span><span class=\"p\">,</span> <span class=\"n\">decoder_inputs</span> <span class=\"o\">=</span> <span class=\"n\">input_transform</span><span class=\"p\">(</span>\n                <span class=\"n\">local_features</span><span class=\"p\">,</span> <span class=\"n\">global_features</span><span class=\"p\">,</span> <span class=\"n\">external_features</span><span class=\"p\">,</span> <span class=\"n\">targets</span><span class=\"p\">)</span>\n\n            <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;GeoMAN&#39;</span><span class=\"p\">):</span>\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;encoder&#39;</span><span class=\"p\">):</span>\n                    <span class=\"n\">encoder_cells</span> <span class=\"o\">=</span> <span class=\"n\">_build_cells</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_encoder_hidden_units</span><span class=\"p\">)</span>\n                    <span class=\"n\">encoder_outputs</span><span class=\"p\">,</span> <span class=\"n\">encoder_state</span><span class=\"p\">,</span> <span class=\"n\">attn_weights</span> <span class=\"o\">=</span> <span class=\"n\">_spatial_attention</span><span class=\"p\">(</span><span class=\"n\">local_features</span><span class=\"p\">,</span>\n                                                                                      <span class=\"n\">global_features</span><span class=\"p\">,</span>\n                                                                                      <span class=\"n\">local_attn_states</span><span class=\"p\">,</span>\n                                                                                      <span class=\"n\">global_attn_states</span><span class=\"p\">,</span>\n                                                                                      <span class=\"n\">encoder_cells</span><span class=\"p\">)</span>\n                    <span class=\"n\">top_states</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">encoder_cells</span><span class=\"o\">.</span><span class=\"n\">output_size</span><span class=\"p\">])</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">encoder_outputs</span><span class=\"p\">]</span>\n                    <span class=\"n\">attention_states</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">top_states</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;decoder&#39;</span><span class=\"p\">):</span>\n                    <span class=\"n\">decoder_cells</span> <span class=\"o\">=</span> <span class=\"n\">_build_cells</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_n_decoder_hidden_units</span><span class=\"p\">)</span>\n                    <span class=\"n\">decoder_outputs</span><span class=\"p\">,</span> <span class=\"n\">states</span> <span class=\"o\">=</span> <span class=\"n\">_temporal_attention</span><span class=\"p\">(</span><span class=\"n\">decoder_inputs</span><span class=\"p\">,</span>\n                                                                  <span class=\"n\">external_features</span><span class=\"p\">,</span>\n                                                                  <span class=\"n\">encoder_state</span><span class=\"p\">,</span>\n                                                                  <span class=\"n\">attention_states</span><span class=\"p\">,</span>\n                                                                  <span class=\"n\">decoder_cells</span><span class=\"p\">)</span>\n\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">):</span>\n                    <span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n                    <span class=\"k\">for</span> <span class=\"n\">decoder_output</span> <span class=\"ow\">in</span> <span class=\"n\">decoder_outputs</span><span class=\"p\">:</span>\n                        <span class=\"n\">predictions</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">predict_layer</span><span class=\"p\">(</span><span class=\"n\">decoder_output</span><span class=\"p\">))</span>\n                    <span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">stack</span><span class=\"p\">(</span><span class=\"n\">predictions</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;predictions&#39;</span><span class=\"p\">)</span>\n\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">):</span>\n                    <span class=\"n\">targets</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">stack</span><span class=\"p\">(</span><span class=\"n\">targets</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;targets&#39;</span><span class=\"p\">)</span>\n                    <span class=\"n\">loss</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">_get_MSE_loss</span><span class=\"p\">(</span><span class=\"n\">targets</span><span class=\"p\">,</span> <span class=\"n\">predictions</span><span class=\"p\">),</span> <span class=\"n\">_get_l2reg_loss</span><span class=\"p\">(),</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">)</span>\n\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">):</span>\n                    <span class=\"n\">global_step</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">get_or_create_global_step</span><span class=\"p\">()</span>\n                    <span class=\"n\">optimizer</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">AdamOptimizer</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span><span class=\"p\">)</span>\n                    <span class=\"n\">gradients</span><span class=\"p\">,</span> <span class=\"n\">variables</span> <span class=\"o\">=</span> <span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">optimizer</span><span class=\"o\">.</span><span class=\"n\">compute_gradients</span><span class=\"p\">(</span><span class=\"n\">loss</span><span class=\"p\">))</span>\n                    <span class=\"n\">gradients</span><span class=\"p\">,</span> <span class=\"n\">_</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">clip_by_global_norm</span><span class=\"p\">(</span><span class=\"n\">gradients</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gc_rate</span><span class=\"p\">)</span>  <span class=\"c1\"># clip norm</span>\n                    <span class=\"n\">train_op</span> <span class=\"o\">=</span> <span class=\"n\">optimizer</span><span class=\"o\">.</span><span class=\"n\">apply_gradients</span><span class=\"p\">(</span><span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"n\">gradients</span><span class=\"p\">,</span> <span class=\"n\">variables</span><span class=\"p\">),</span> <span class=\"n\">global_step</span><span class=\"p\">)</span>\n\n                <span class=\"c1\"># record output</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">predictions</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">loss</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"c1\"># record op</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">train_op</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">GeoMAN</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">(</span><span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"n\">init_vars</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span></div>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_get_feed_dict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                       <span class=\"n\">local_features</span><span class=\"p\">,</span>\n                       <span class=\"n\">global_features</span><span class=\"p\">,</span>\n                       <span class=\"n\">local_attn_states</span><span class=\"p\">,</span>\n                       <span class=\"n\">global_attn_states</span><span class=\"p\">,</span>\n                       <span class=\"n\">external_features</span><span class=\"p\">,</span>\n                       <span class=\"n\">targets</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;The method to get feet dict for tensorflow model.</span>\n\n<span class=\"sd\">        Users may modify this method according to the format of input.</span>\n\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            local_features (np.ndarray): All the time series generated by the target sensor i, including one target</span>\n<span class=\"sd\">                series and other feature series, with shape `(batch, input_steps, input_dim)`.</span>\n<span class=\"sd\">            global_features (np.ndarray): Target series generated by all the sensors, with shape `(batch, input_steps,</span>\n<span class=\"sd\">                total_sensors)`.</span>\n<span class=\"sd\">            local_attn_states (np.ndarray): Equals to ``local_features`` swapped ``input_steps`` and ``input_dim`` axis,</span>\n<span class=\"sd\">                with shape `(batch, input_dim, input_steps)`.</span>\n<span class=\"sd\">            global_attn_states (np.ndarray): All time series generated by all sensors, with shape `(batch,</span>\n<span class=\"sd\">                total_sensors, input_dim, input_steps)`.</span>\n<span class=\"sd\">            external_features (np.ndarray): Fused external factors, e.g., temporal factors: meteorology and spatial</span>\n<span class=\"sd\">                factors: POIs density, with shape `(batch, output_steps, external_dim)`. All features have to be</span>\n<span class=\"sd\">                time series.</span>\n<span class=\"sd\">            targets (np.ndarray): Target sensor&#39;s labels, with shape `(batch, output_steps, output_dim)`.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">feed_dict</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">&#39;local_features&#39;</span><span class=\"p\">:</span> <span class=\"n\">local_features</span><span class=\"p\">,</span> <span class=\"s1\">&#39;global_features&#39;</span><span class=\"p\">:</span> <span class=\"n\">global_features</span><span class=\"p\">,</span>\n                     <span class=\"s1\">&#39;local_attn_states&#39;</span><span class=\"p\">:</span> <span class=\"n\">local_attn_states</span><span class=\"p\">,</span> <span class=\"s1\">&#39;global_attn_states&#39;</span><span class=\"p\">:</span> <span class=\"n\">global_attn_states</span><span class=\"p\">,</span>\n                     <span class=\"s1\">&#39;external_features&#39;</span><span class=\"p\">:</span> <span class=\"n\">external_features</span><span class=\"p\">,</span> <span class=\"s1\">&#39;targets&#39;</span><span class=\"p\">:</span> <span class=\"n\">targets</span><span class=\"p\">}</span>\n        <span class=\"k\">return</span> <span class=\"n\">feed_dict</span></div>\n\n\n<div class=\"viewcode-block\" id=\"input_transform\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.GeoMAN.input_transform\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">input_transform</span><span class=\"p\">(</span><span class=\"n\">local_features</span><span class=\"p\">,</span>\n                    <span class=\"n\">global_features</span><span class=\"p\">,</span>\n                    <span class=\"n\">external_features</span><span class=\"p\">,</span>\n                    <span class=\"n\">targets</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Split the model&#39;s inputs from matrices to lists on timesteps axis.&quot;&quot;&quot;</span>\n    <span class=\"n\">local_features</span> <span class=\"o\">=</span> <span class=\"n\">split_timesteps</span><span class=\"p\">(</span><span class=\"n\">local_features</span><span class=\"p\">)</span>\n    <span class=\"n\">global_features</span> <span class=\"o\">=</span> <span class=\"n\">split_timesteps</span><span class=\"p\">(</span><span class=\"n\">global_features</span><span class=\"p\">)</span>\n    <span class=\"n\">external_features</span> <span class=\"o\">=</span> <span class=\"n\">split_timesteps</span><span class=\"p\">(</span><span class=\"n\">external_features</span><span class=\"p\">)</span>\n    <span class=\"n\">targets</span> <span class=\"o\">=</span> <span class=\"n\">split_timesteps</span><span class=\"p\">(</span><span class=\"n\">targets</span><span class=\"p\">)</span>\n    <span class=\"n\">decoder_inputs</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">zeros_like</span><span class=\"p\">(</span><span class=\"n\">targets</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)]</span> <span class=\"o\">+</span> <span class=\"n\">targets</span><span class=\"p\">[:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>  <span class=\"c1\"># useless when loop func is employed</span>\n    <span class=\"k\">return</span> <span class=\"n\">local_features</span><span class=\"p\">,</span> <span class=\"n\">global_features</span><span class=\"p\">,</span> <span class=\"n\">external_features</span><span class=\"p\">,</span> <span class=\"n\">targets</span><span class=\"p\">,</span> <span class=\"n\">decoder_inputs</span></div>\n\n\n<div class=\"viewcode-block\" id=\"split_timesteps\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.GeoMAN.split_timesteps\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">split_timesteps</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Split the input matrix from (batch, timesteps, input_dim) to a step list ([[batch, input_dim], ..., ]).&quot;&quot;&quot;</span>\n    <span class=\"n\">timesteps</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n    <span class=\"n\">feature_dims</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n    <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">])</span>\n    <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">feature_dims</span><span class=\"p\">])</span>\n    <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">timesteps</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">inputs</span></div>\n\n\n\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model/HM.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model.HM &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model.HM</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">warnings</span>\n<span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">filterwarnings</span><span class=\"p\">(</span><span class=\"s2\">&quot;ignore&quot;</span><span class=\"p\">)</span>\n\n\n<div class=\"viewcode-block\" id=\"HM\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.HM.HM\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">HM</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">,</span> <span class=\"n\">p</span><span class=\"p\">,</span> <span class=\"n\">t</span><span class=\"p\">):</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">c</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">p</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"n\">t</span>\n\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">c</span> <span class=\"o\">==</span> <span class=\"mi\">0</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">p</span> <span class=\"o\">==</span> <span class=\"mi\">0</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">t</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;c p t cannot all be zero at the same time&#39;</span><span class=\"p\">)</span>\n\n<div class=\"viewcode-block\" id=\"HM.predict\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.HM.HM.predict\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">closeness_feature</span><span class=\"p\">,</span> <span class=\"n\">period_feature</span><span class=\"p\">,</span> <span class=\"n\">trend_feature</span><span class=\"p\">):</span>\n\n        <span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">c</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">prediction</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">closeness_feature</span><span class=\"p\">[:,</span> <span class=\"p\">:,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">p</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">prediction</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">period_feature</span><span class=\"p\">[:,</span> <span class=\"p\">:,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">t</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">prediction</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">trend_feature</span><span class=\"p\">[:,</span> <span class=\"p\">:,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n\n        <span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">keepdims</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">prediction</span></div></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model/HMM.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model.HMM &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model.HMM</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">from</span> <span class=\"nn\">hmmlearn</span> <span class=\"k\">import</span> <span class=\"n\">hmm</span>\n\n\n<div class=\"viewcode-block\" id=\"HMM\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.HMM.HMM\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">HMM</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">num_components</span><span class=\"p\">,</span> <span class=\"n\">n_iter</span><span class=\"p\">,</span> <span class=\"n\">hmm_kernal</span><span class=\"o\">=</span><span class=\"n\">hmm</span><span class=\"o\">.</span><span class=\"n\">GaussianHMM</span><span class=\"p\">):</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_components</span> <span class=\"o\">=</span> <span class=\"n\">num_components</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_iter</span> <span class=\"o\">=</span> <span class=\"n\">n_iter</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_hmm</span> <span class=\"o\">=</span> <span class=\"n\">hmm_kernal</span><span class=\"p\">(</span><span class=\"n\">n_components</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_components</span><span class=\"p\">,</span> <span class=\"n\">n_iter</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_iter</span><span class=\"p\">,</span> <span class=\"n\">covariance_type</span><span class=\"o\">=</span><span class=\"s1\">&#39;full&#39;</span><span class=\"p\">)</span>\n\n<div class=\"viewcode-block\" id=\"HMM.fit\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.HMM.HMM.fit\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">fit</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">x</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_hmm</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_hmm</span><span class=\"o\">.</span><span class=\"n\">monitor_</span><span class=\"o\">.</span><span class=\"n\">converged</span><span class=\"p\">:</span>\n            <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Status: converged&#39;</span><span class=\"p\">)</span></div>\n\n<div class=\"viewcode-block\" id=\"HMM.predict\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.HMM.HMM.predict\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">length</span><span class=\"p\">):</span>\n        <span class=\"c1\"># predict the state for each element of X</span>\n        <span class=\"c1\"># and store the last state</span>\n        <span class=\"n\">last_state</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_hmm</span><span class=\"o\">.</span><span class=\"n\">predict_proba</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:]</span>\n\n        <span class=\"n\">pre_state</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"n\">pre_observation</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">length</span><span class=\"p\">):</span>\n            <span class=\"c1\"># predict the state of next moment using the transmat</span>\n            <span class=\"n\">last_state</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">dot</span><span class=\"p\">(</span><span class=\"n\">last_state</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_hmm</span><span class=\"o\">.</span><span class=\"n\">transmat_</span><span class=\"p\">)</span>\n\n            <span class=\"n\">pre_state</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">last_state</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># dot product between the state-probability and state-means</span>\n            <span class=\"n\">pre_observation</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">([</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">dot</span><span class=\"p\">(</span><span class=\"n\">last_state</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_hmm</span><span class=\"o\">.</span><span class=\"n\">means_</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">]])</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">pre_observation</span></div></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model/STMeta.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model.STMeta &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model.STMeta</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">keras</span>\n<span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">BaseModel</span>\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">GAL</span><span class=\"p\">,</span> <span class=\"n\">GCL</span>\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">DCGRUCell</span>\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">GCLSTMCell</span>\n\n\n<div class=\"viewcode-block\" id=\"STMeta\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.STMeta.STMeta\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">STMeta</span><span class=\"p\">(</span><span class=\"n\">BaseModel</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            num_node(int): Number of nodes in the graph, e.g. number of stations in NYC-Bike dataset.</span>\n<span class=\"sd\">            external_dim(int): Dimension of the external feature, e.g. temperature and wind are two dimension.</span>\n<span class=\"sd\">            closeness_len(int): The length of closeness data history. The former consecutive ``closeness_len`` time slots</span>\n<span class=\"sd\">            of data will be used as closeness history.</span>\n<span class=\"sd\">            period_len(int): The length of period data history. The data of exact same time slots in former consecutive</span>\n<span class=\"sd\">            ``period_len`` days will be used as period history.</span>\n<span class=\"sd\">            trend_len(int): The length of trend data history. The data of exact same time slots in former consecutive</span>\n<span class=\"sd\">            ``trend_len`` weeks (every seven days) will be used as trend history.</span>\n<span class=\"sd\">            num_graph(int): Number of graphs used in STMeta.</span>\n<span class=\"sd\">            gcn_k(int): The highest order of Chebyshev Polynomial approximation in GCN.</span>\n<span class=\"sd\">            gcn_layers(int): Number of GCN layers.</span>\n<span class=\"sd\">            gclstm_layers(int): Number of STRNN layers, it works on all modes of STMeta such as GCLSTM and DCRNN.</span>\n<span class=\"sd\">            num_hidden_units(int): Number of hidden units of RNN.</span>\n<span class=\"sd\">            num_dense_units(int): Number of dense units.</span>\n<span class=\"sd\">            graph_merge_gal_units(int): Number of units in GAL for merging different graph features.</span>\n<span class=\"sd\">                Only works when graph_merge=&#39;gal&#39;</span>\n<span class=\"sd\">            graph_merge_gal_num_heads(int): Number of heads in GAL for merging different graph features.</span>\n<span class=\"sd\">                Only works when graph_merge=&#39;gal&#39;</span>\n<span class=\"sd\">            temporal_merge_gal_units(int): Number of units in GAL for merging different temporal features.</span>\n<span class=\"sd\">                Only works when temporal_merge=&#39;gal&#39;</span>\n<span class=\"sd\">            temporal_merge_gal_num_heads(int): Number of heads in GAL for merging different temporal features.</span>\n<span class=\"sd\">                Only works when temporal_merge=&#39;gal&#39;</span>\n<span class=\"sd\">            st_method(str): must in [&#39;GCLSTM&#39;, &#39;DCRNN&#39;, &#39;GRU&#39;, &#39;LSTM&#39;], which refers to different</span>\n<span class=\"sd\">                spatial-temporal modeling methods.</span>\n<span class=\"sd\">                &#39;GCLSTM&#39;: GCN for modeling spatial feature, LSTM for modeling temporal feature.</span>\n<span class=\"sd\">                &#39;DCRNN&#39;: Diffusion Convolution for modeling spatial feature, GRU for modeling temporam frature.</span>\n<span class=\"sd\">                &#39;GRU&#39;: Ignore the spatial, and model the temporal feature using GRU</span>\n<span class=\"sd\">                &#39;LSTM&#39;: Ignore the spatial, and model the temporal feature using LSTM</span>\n<span class=\"sd\">            temporal_merge(str): must in [&#39;gal&#39;, &#39;concat&#39;], refers to different temporal merging methods,</span>\n<span class=\"sd\">                &#39;gal&#39;: merge using GAL,</span>\n<span class=\"sd\">                &#39;concat&#39;: merge by concat and dense</span>\n<span class=\"sd\">            graph_merge(str): must in [&#39;gal&#39;, &#39;concat&#39;], refers to different graph merging methods,</span>\n<span class=\"sd\">                &#39;gal&#39;: merge using GAL,</span>\n<span class=\"sd\">                &#39;concat&#39;: merge by concat and dense</span>\n<span class=\"sd\">            output_activation(function): activation function, e.g. tf.nn.tanh</span>\n<span class=\"sd\">            lr(float): Learning rate. Default: 1e-5</span>\n<span class=\"sd\">            code_version(str): Current version of this model code, which will be used as filename for saving the model</span>\n<span class=\"sd\">            model_dir(str): The directory to store model files. Default:&#39;model_dir&#39;.</span>\n<span class=\"sd\">            gpu_device(str): To specify the GPU to use. Default: &#39;0&#39;.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 <span class=\"n\">num_node</span><span class=\"p\">,</span>\n                 <span class=\"n\">external_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">closeness_len</span><span class=\"p\">,</span>\n                 <span class=\"n\">period_len</span><span class=\"p\">,</span>\n                 <span class=\"n\">trend_len</span><span class=\"p\">,</span>\n\n                 <span class=\"c1\"># gcn parameters</span>\n                 <span class=\"n\">num_graph</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">gcn_k</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">gcn_layers</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">gclstm_layers</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n\n                 <span class=\"c1\"># dense units</span>\n                 <span class=\"n\">num_hidden_units</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span>\n                 <span class=\"c1\"># LSTM units</span>\n                 <span class=\"n\">num_dense_units</span><span class=\"o\">=</span><span class=\"mi\">32</span><span class=\"p\">,</span>\n\n                 <span class=\"c1\"># merge parameters</span>\n                 <span class=\"n\">graph_merge_gal_units</span><span class=\"o\">=</span><span class=\"mi\">32</span><span class=\"p\">,</span>\n                 <span class=\"n\">graph_merge_gal_num_heads</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n                 <span class=\"n\">temporal_merge_gal_units</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span>\n                 <span class=\"n\">temporal_merge_gal_num_heads</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n\n                 <span class=\"c1\"># network structure parameters</span>\n                 <span class=\"n\">st_method</span><span class=\"o\">=</span><span class=\"s1\">&#39;GCLSTM&#39;</span><span class=\"p\">,</span>  <span class=\"c1\"># gclstm</span>\n                 <span class=\"n\">temporal_merge</span><span class=\"o\">=</span><span class=\"s1\">&#39;gal&#39;</span><span class=\"p\">,</span>  <span class=\"c1\"># gal</span>\n                 <span class=\"n\">graph_merge</span><span class=\"o\">=</span><span class=\"s1\">&#39;gal&#39;</span><span class=\"p\">,</span>  <span class=\"c1\"># concat</span>\n\n                 <span class=\"n\">output_activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">sigmoid</span><span class=\"p\">,</span>\n\n                 <span class=\"n\">lr</span><span class=\"o\">=</span><span class=\"mf\">1e-4</span><span class=\"p\">,</span>\n                 <span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"s1\">&#39;STMeta-QuickStart&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;model_dir&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">STMeta</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"n\">code_version</span><span class=\"p\">,</span> <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"n\">model_dir</span><span class=\"p\">,</span> <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"n\">gpu_device</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span> <span class=\"o\">=</span> <span class=\"n\">num_node</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span> <span class=\"o\">=</span> <span class=\"n\">gcn_k</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_layer</span> <span class=\"o\">=</span> <span class=\"n\">gcn_layers</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph_merge_gal_units</span> <span class=\"o\">=</span> <span class=\"n\">graph_merge_gal_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph_merge_gal_num_heads</span> <span class=\"o\">=</span> <span class=\"n\">graph_merge_gal_num_heads</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_temporal_merge_gal_units</span> <span class=\"o\">=</span> <span class=\"n\">temporal_merge_gal_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_temporal_merge_gal_num_heads</span> <span class=\"o\">=</span> <span class=\"n\">temporal_merge_gal_num_heads</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gclstm_layers</span> <span class=\"o\">=</span> <span class=\"n\">gclstm_layers</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_graph</span> <span class=\"o\">=</span> <span class=\"n\">num_graph</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">=</span> <span class=\"n\">external_dim</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output_activation</span> <span class=\"o\">=</span> <span class=\"n\">output_activation</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_st_method</span> <span class=\"o\">=</span> <span class=\"n\">st_method</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_temporal_merge</span> <span class=\"o\">=</span> <span class=\"n\">temporal_merge</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph_merge</span> <span class=\"o\">=</span> <span class=\"n\">graph_merge</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">closeness_len</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">period_len</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">trend_len</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_hidden_unit</span> <span class=\"o\">=</span> <span class=\"n\">num_hidden_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_dense_units</span> <span class=\"o\">=</span> <span class=\"n\">num_dense_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span> <span class=\"o\">=</span> <span class=\"n\">lr</span>\n    \n<div class=\"viewcode-block\" id=\"STMeta.build\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.STMeta.STMeta.build\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n\n            <span class=\"n\">temporal_features</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">closeness_feature</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span>\n                                                   <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;closeness_feature&#39;</span><span class=\"p\">)</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;closeness_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">closeness_feature</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"n\">temporal_features</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">([</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span><span class=\"p\">,</span> <span class=\"n\">closeness_feature</span><span class=\"p\">,</span> <span class=\"s1\">&#39;closeness_feature&#39;</span><span class=\"p\">])</span>\n\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">period_feature</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span>\n                                                <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;period_feature&#39;</span><span class=\"p\">)</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;period_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">period_feature</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"n\">temporal_features</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">([</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span><span class=\"p\">,</span> <span class=\"n\">period_feature</span><span class=\"p\">,</span> <span class=\"s1\">&#39;period_feature&#39;</span><span class=\"p\">])</span>\n\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">trend_feature</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span>\n                                               <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;trend_feature&#39;</span><span class=\"p\">)</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;trend_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">trend_feature</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"n\">temporal_features</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">([</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span><span class=\"p\">,</span> <span class=\"n\">trend_feature</span><span class=\"p\">,</span> <span class=\"s1\">&#39;trend_feature&#39;</span><span class=\"p\">])</span>\n\n            <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">temporal_features</span><span class=\"p\">)</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">target</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">)</span>\n                <span class=\"n\">laplace_matrix</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_graph</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;laplace_matrix&#39;</span><span class=\"p\">)</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">target</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;laplace_matrix&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">laplace_matrix</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;closeness_len, period_len, trend_len cannot all be zero&#39;</span><span class=\"p\">)</span>\n\n            <span class=\"n\">graph_outputs_list</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n            <span class=\"k\">for</span> <span class=\"n\">graph_index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_graph</span><span class=\"p\">):</span>\n\n                <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_st_method</span> <span class=\"ow\">in</span> <span class=\"p\">[</span><span class=\"s1\">&#39;GCLSTM&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;DCRNN&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;GRU&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;LSTM&#39;</span><span class=\"p\">]:</span>\n\n                    <span class=\"n\">outputs_temporal</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n                    <span class=\"k\">for</span> <span class=\"n\">time_step</span><span class=\"p\">,</span> <span class=\"n\">target_tensor</span><span class=\"p\">,</span> <span class=\"n\">given_name</span> <span class=\"ow\">in</span> <span class=\"n\">temporal_features</span><span class=\"p\">:</span>\n\n                        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_st_method</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;GCLSTM&#39;</span><span class=\"p\">:</span>\n\n                            <span class=\"n\">multi_layer_cell</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">StackedRNNCells</span><span class=\"p\">(</span>\n                                <span class=\"p\">[</span><span class=\"n\">GCLSTMCell</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_hidden_unit</span><span class=\"p\">,</span> <span class=\"n\">num_nodes</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span>\n                                            <span class=\"n\">laplacian_matrix</span><span class=\"o\">=</span><span class=\"n\">laplace_matrix</span><span class=\"p\">[</span><span class=\"n\">graph_index</span><span class=\"p\">],</span>\n                                            <span class=\"n\">gcn_k</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span><span class=\"p\">,</span> <span class=\"n\">gcn_l</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_layer</span><span class=\"p\">)</span>\n                                 <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gclstm_layers</span><span class=\"p\">)])</span>\n\n                            <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">RNN</span><span class=\"p\">(</span><span class=\"n\">multi_layer_cell</span><span class=\"p\">)(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">target_tensor</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">time_step</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]))</span>\n\n                            <span class=\"n\">st_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_hidden_unit</span><span class=\"p\">])</span>\n\n                        <span class=\"k\">elif</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_st_method</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;DCRNN&#39;</span><span class=\"p\">:</span>\n\n                            <span class=\"n\">cell</span> <span class=\"o\">=</span> <span class=\"n\">DCGRUCell</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_hidden_unit</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_graph</span><span class=\"p\">,</span>\n                                             <span class=\"c1\"># laplace_matrix will be diffusion_matrix when self._st_method == &#39;DCRNN&#39;</span>\n                                             <span class=\"n\">laplace_matrix</span><span class=\"p\">,</span>\n                                             <span class=\"n\">max_diffusion_step</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span><span class=\"p\">,</span>\n                                             <span class=\"n\">num_nodes</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">graph_index</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">given_name</span><span class=\"p\">)</span>\n\n                            <span class=\"n\">encoding_cells</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">cell</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gclstm_layers</span>\n                            <span class=\"n\">encoding_cells</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">rnn</span><span class=\"o\">.</span><span class=\"n\">MultiRNNCell</span><span class=\"p\">(</span><span class=\"n\">encoding_cells</span><span class=\"p\">,</span> <span class=\"n\">state_is_tuple</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n                            <span class=\"n\">inputs_unstack</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">unstack</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">target_tensor</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"n\">time_step</span><span class=\"p\">]),</span>\n                                                        <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n                            <span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">_</span> <span class=\"o\">=</span> \\\n                                <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">rnn</span><span class=\"o\">.</span><span class=\"n\">static_rnn</span><span class=\"p\">(</span><span class=\"n\">encoding_cells</span><span class=\"p\">,</span> <span class=\"n\">inputs_unstack</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n                            <span class=\"n\">st_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_hidden_unit</span><span class=\"p\">])</span>\n\n                        <span class=\"k\">elif</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_st_method</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;GRU&#39;</span><span class=\"p\">:</span>\n\n                            <span class=\"n\">cell</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">GRUCell</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_hidden_unit</span><span class=\"p\">)</span>\n                            <span class=\"n\">multi_layer_gru</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">StackedRNNCells</span><span class=\"p\">([</span><span class=\"n\">cell</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gclstm_layers</span><span class=\"p\">)</span>\n                            <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">RNN</span><span class=\"p\">(</span><span class=\"n\">multi_layer_gru</span><span class=\"p\">)(</span>\n                                <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">target_tensor</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">time_step</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]))</span>\n                            <span class=\"n\">st_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_hidden_unit</span><span class=\"p\">])</span>\n\n                        <span class=\"k\">elif</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_st_method</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;LSTM&#39;</span><span class=\"p\">:</span>\n\n                            <span class=\"n\">cell</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">LSTMCell</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_hidden_unit</span><span class=\"p\">)</span>\n                            <span class=\"n\">multi_layer_gru</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">StackedRNNCells</span><span class=\"p\">([</span><span class=\"n\">cell</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gclstm_layers</span><span class=\"p\">)</span>\n                            <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">RNN</span><span class=\"p\">(</span><span class=\"n\">multi_layer_gru</span><span class=\"p\">)(</span>\n                                <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">target_tensor</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">time_step</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]))</span>\n                            <span class=\"n\">st_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_hidden_unit</span><span class=\"p\">])</span>\n\n                        <span class=\"n\">outputs_temporal</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">st_outputs</span><span class=\"p\">)</span>\n\n                    <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_temporal_merge</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;concat&#39;</span><span class=\"p\">:</span>\n                        \n                        <span class=\"n\">graph_outputs_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">outputs_temporal</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n\n                    <span class=\"k\">elif</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_temporal_merge</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;gal&#39;</span><span class=\"p\">:</span>\n\n                        <span class=\"n\">_</span><span class=\"p\">,</span> <span class=\"n\">gal_output</span> <span class=\"o\">=</span> <span class=\"n\">GAL</span><span class=\"o\">.</span><span class=\"n\">add_ga_layer_matrix</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">outputs_temporal</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">),</span>\n                                                                <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_temporal_merge_gal_units</span><span class=\"p\">,</span>\n                                                                <span class=\"n\">num_head</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_temporal_merge_gal_num_heads</span><span class=\"p\">)</span>\n\n                        <span class=\"n\">graph_outputs_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">gal_output</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">keepdims</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">))</span>\n\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_graph</span> <span class=\"o\">&gt;</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n\n                <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph_merge</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;gal&#39;</span><span class=\"p\">:</span>\n                    <span class=\"c1\"># (graph, inputs_name, units, num_head, activation=tf.nn.leaky_relu)</span>\n                    <span class=\"n\">_</span><span class=\"p\">,</span> <span class=\"n\">gal_output</span> <span class=\"o\">=</span> <span class=\"n\">GAL</span><span class=\"o\">.</span><span class=\"n\">add_ga_layer_matrix</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">graph_outputs_list</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">),</span>\n                                                            <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph_merge_gal_units</span><span class=\"p\">,</span>\n                                                            <span class=\"n\">num_head</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph_merge_gal_num_heads</span><span class=\"p\">)</span>\n                    <span class=\"n\">dense_inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">gal_output</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">keepdims</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n                <span class=\"k\">elif</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph_merge</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;concat&#39;</span><span class=\"p\">:</span>\n\n                    <span class=\"n\">dense_inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">graph_outputs_list</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n\n                <span class=\"n\">dense_inputs</span> <span class=\"o\">=</span> <span class=\"n\">graph_outputs_list</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n\n            <span class=\"n\">dense_inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">dense_inputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">dense_inputs</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span><span class=\"p\">])</span>\n\n            <span class=\"n\">dense_inputs</span> <span class=\"o\">=</span> <span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">BatchNormalization</span><span class=\"p\">(</span><span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;feature_map&#39;</span><span class=\"p\">)(</span><span class=\"n\">dense_inputs</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># external dims</span>\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">external_input</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span><span class=\"p\">])</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;external_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">external_input</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"n\">external_dense</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">Dense</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)(</span><span class=\"n\">external_input</span><span class=\"p\">)</span>\n                <span class=\"n\">external_dense</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">external_dense</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">]),</span>\n                                         <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">dense_inputs</span><span class=\"p\">)[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">dense_inputs</span><span class=\"p\">)[</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n                <span class=\"n\">dense_inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">dense_inputs</span><span class=\"p\">,</span> <span class=\"n\">external_dense</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"n\">dense_output0</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">Dense</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_dense_units</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">kernel_initializer</span><span class=\"o\">=</span><span class=\"s1\">&#39;glorot_uniform&#39;</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">bias_initializer</span><span class=\"o\">=</span><span class=\"s1\">&#39;zeros&#39;</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">kernel_regularizer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">regularizers</span><span class=\"o\">.</span><span class=\"n\">l2</span><span class=\"p\">(</span><span class=\"mf\">0.01</span><span class=\"p\">),</span>\n                                                  <span class=\"n\">bias_regularizer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">regularizers</span><span class=\"o\">.</span><span class=\"n\">l2</span><span class=\"p\">(</span><span class=\"mf\">0.01</span><span class=\"p\">)</span>\n                                                  <span class=\"p\">)(</span><span class=\"n\">dense_inputs</span><span class=\"p\">)</span>\n\n            <span class=\"n\">dense_output1</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">Dense</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_dense_units</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">kernel_initializer</span><span class=\"o\">=</span><span class=\"s1\">&#39;glorot_uniform&#39;</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">bias_initializer</span><span class=\"o\">=</span><span class=\"s1\">&#39;zeros&#39;</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">kernel_regularizer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">regularizers</span><span class=\"o\">.</span><span class=\"n\">l2</span><span class=\"p\">(</span><span class=\"mf\">0.01</span><span class=\"p\">),</span>\n                                                  <span class=\"n\">bias_regularizer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">regularizers</span><span class=\"o\">.</span><span class=\"n\">l2</span><span class=\"p\">(</span><span class=\"mf\">0.01</span><span class=\"p\">)</span>\n                                                  <span class=\"p\">)(</span><span class=\"n\">dense_output0</span><span class=\"p\">)</span>\n\n            <span class=\"n\">pre_output</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">Dense</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                                               <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">,</span>\n                                               <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                                               <span class=\"n\">kernel_initializer</span><span class=\"o\">=</span><span class=\"s1\">&#39;glorot_uniform&#39;</span><span class=\"p\">,</span>\n                                               <span class=\"n\">bias_initializer</span><span class=\"o\">=</span><span class=\"s1\">&#39;zeros&#39;</span><span class=\"p\">,</span>\n                                               <span class=\"n\">kernel_regularizer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">regularizers</span><span class=\"o\">.</span><span class=\"n\">l2</span><span class=\"p\">(</span><span class=\"mf\">0.01</span><span class=\"p\">),</span>\n                                               <span class=\"n\">bias_regularizer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">regularizers</span><span class=\"o\">.</span><span class=\"n\">l2</span><span class=\"p\">(</span><span class=\"mf\">0.01</span><span class=\"p\">)</span>\n                                               <span class=\"p\">)(</span><span class=\"n\">dense_output1</span><span class=\"p\">)</span>\n\n            <span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">pre_output</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">)</span>\n\n            <span class=\"n\">loss_pre</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">target</span> <span class=\"o\">-</span> <span class=\"n\">prediction</span><span class=\"p\">)),</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">)</span>\n\n            <span class=\"n\">train_op</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">AdamOptimizer</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">minimize</span><span class=\"p\">(</span><span class=\"n\">loss_pre</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># record output</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">prediction</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">loss_pre</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"c1\"># record train operation</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">train_op</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">STMeta</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">(</span><span class=\"n\">init_vars</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"p\">)</span></div>\n\n    <span class=\"c1\"># Define your &#39;_get_feed_dict function‘, map your input to the tf-model</span>\n    <span class=\"k\">def</span> <span class=\"nf\">_get_feed_dict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                       <span class=\"n\">laplace_matrix</span><span class=\"p\">,</span>\n                       <span class=\"n\">closeness_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                       <span class=\"n\">period_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                       <span class=\"n\">trend_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                       <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                       <span class=\"n\">external_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"n\">feed_dict</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n            <span class=\"s1\">&#39;laplace_matrix&#39;</span><span class=\"p\">:</span> <span class=\"n\">laplace_matrix</span><span class=\"p\">,</span>\n        <span class=\"p\">}</span>\n        <span class=\"k\">if</span> <span class=\"n\">target</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">target</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;external_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">external_feature</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;closeness_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">closeness_feature</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;period_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">period_feature</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;trend_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">trend_feature</span>\n        <span class=\"k\">return</span> <span class=\"n\">feed_dict</span></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model/ST_MGCN.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model.ST_MGCN &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model.ST_MGCN</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">BaseModel</span>\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit.GraphModelLayers</span> <span class=\"k\">import</span> <span class=\"n\">GCL</span>\n\n\n<div class=\"viewcode-block\" id=\"ST_MGCN\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.ST_MGCN.ST_MGCN\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">ST_MGCN</span><span class=\"p\">(</span><span class=\"n\">BaseModel</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    Args:</span>\n<span class=\"sd\">        T(int): Input sequence length</span>\n<span class=\"sd\">        input_dim(int): Input feature dimension</span>\n<span class=\"sd\">        num_graph(int): Number of graphs used in the model.</span>\n<span class=\"sd\">        gcl_k(int): The highest order of Chebyshev Polynomial approximation in GCN.</span>\n<span class=\"sd\">        gcl_l(int): Number of GCN layers.</span>\n<span class=\"sd\">        lstm_units(int): Number of hidden units of RNN.</span>\n<span class=\"sd\">        lstm_layers(int): Number of LSTM layers.</span>\n<span class=\"sd\">        lr(float): Learning rate</span>\n<span class=\"sd\">        external_dim(int): Dimension of the external feature, e.g. temperature and wind are two dimension.</span>\n<span class=\"sd\">        code_version(str): Current version of this model code, which will be used as filename for saving the model</span>\n<span class=\"sd\">        model_dir(str): The directory to store model files. Default:&#39;model_dir&#39;.</span>\n<span class=\"sd\">        gpu_device(str): To specify the GPU to use. Default: &#39;0&#39;.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 <span class=\"n\">T</span><span class=\"p\">,</span>\n                 <span class=\"n\">input_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">num_graph</span><span class=\"p\">,</span>\n                 <span class=\"n\">gcl_k</span><span class=\"p\">,</span>\n                 <span class=\"n\">gcl_l</span><span class=\"p\">,</span>\n                 <span class=\"n\">lstm_units</span><span class=\"p\">,</span>\n                 <span class=\"n\">lstm_layers</span><span class=\"p\">,</span>\n                 <span class=\"n\">lr</span><span class=\"p\">,</span>\n                 <span class=\"n\">external_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">code_version</span><span class=\"p\">,</span>\n                 <span class=\"n\">model_dir</span><span class=\"p\">,</span>\n                 <span class=\"n\">gpu_device</span><span class=\"p\">):</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">ST_MGCN</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"n\">code_version</span><span class=\"p\">,</span>\n                                      <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"n\">model_dir</span><span class=\"p\">,</span>\n                                      <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"n\">gpu_device</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_T</span> <span class=\"o\">=</span> <span class=\"n\">T</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span> <span class=\"o\">=</span> <span class=\"n\">input_dim</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_graph</span> <span class=\"o\">=</span> <span class=\"n\">num_graph</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcl_k</span> <span class=\"o\">=</span> <span class=\"n\">gcl_k</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcl_l</span> <span class=\"o\">=</span> <span class=\"n\">gcl_l</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lstm_units</span> <span class=\"o\">=</span> <span class=\"n\">lstm_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lstm_layers</span> <span class=\"o\">=</span> <span class=\"n\">lstm_layers</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span> <span class=\"o\">=</span> <span class=\"n\">lr</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">=</span> <span class=\"n\">external_dim</span>\n\n<div class=\"viewcode-block\" id=\"ST_MGCN.build\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.ST_MGCN.ST_MGCN.build\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n            <span class=\"c1\"># [batch, T, num_stations, input_dim]</span>\n            <span class=\"n\">traffic_flow</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_T</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span><span class=\"p\">])</span>\n            <span class=\"n\">laplacian_matrix</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_graph</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">])</span>\n            <span class=\"n\">target</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;traffic_flow&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">traffic_flow</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;laplace_matrix&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">laplacian_matrix</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">target</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"n\">station_number</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">traffic_flow</span><span class=\"p\">)[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">]</span>\n\n            <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n            <span class=\"k\">for</span> <span class=\"n\">graph_index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_graph</span><span class=\"p\">):</span>\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;CGRNN_Graph</span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">graph_index</span><span class=\"p\">,</span> <span class=\"n\">reuse</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span>\n                    <span class=\"n\">f_k_g</span> <span class=\"o\">=</span> <span class=\"n\">GCL</span><span class=\"o\">.</span><span class=\"n\">add_multi_gc_layers</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">traffic_flow</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">station_number</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span><span class=\"p\">]),</span>\n                                                    <span class=\"n\">gcn_k</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">gcn_l</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span><span class=\"p\">,</span>\n                                                    <span class=\"n\">laplacian_matrix</span><span class=\"o\">=</span><span class=\"n\">laplacian_matrix</span><span class=\"p\">[</span><span class=\"n\">graph_index</span><span class=\"p\">],</span>\n                                                    <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">)</span>\n\n                    <span class=\"n\">f_k_g</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">f_k_g</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_T</span><span class=\"p\">,</span> <span class=\"n\">station_number</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span><span class=\"p\">])</span>\n\n                    <span class=\"n\">x_hat</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">f_k_g</span><span class=\"p\">,</span> <span class=\"n\">traffic_flow</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n                    <span class=\"n\">z</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">x_hat</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">keepdims</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n                    <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">dense</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">dense</span><span class=\"p\">(</span><span class=\"n\">z</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">relu</span><span class=\"p\">),</span>\n                                        <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">sigmoid</span><span class=\"p\">)</span>\n\n                    <span class=\"n\">x_rnn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">multiply</span><span class=\"p\">(</span><span class=\"n\">traffic_flow</span><span class=\"p\">,</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">station_number</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span><span class=\"p\">]))</span>\n\n                    <span class=\"n\">x_rnn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">x_rnn</span><span class=\"p\">,</span> <span class=\"n\">perm</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_T</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span><span class=\"p\">])</span>\n\n                    <span class=\"k\">for</span> <span class=\"n\">lstm_layer_index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lstm_layers</span><span class=\"p\">):</span>\n                        <span class=\"n\">x_rnn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">LSTM</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lstm_units</span><span class=\"p\">,</span>\n                                                     <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"s1\">&#39;tanh&#39;</span><span class=\"p\">,</span>\n                                                     <span class=\"n\">dropout</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span>\n                                                     <span class=\"n\">kernel_regularizer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">l2_regularizer</span><span class=\"p\">(</span><span class=\"mf\">1e-4</span><span class=\"p\">),</span>\n                                                     <span class=\"n\">return_sequences</span><span class=\"o\">=</span><span class=\"kc\">True</span> <span class=\"k\">if</span> <span class=\"n\">lstm_layer_index</span><span class=\"o\">&lt;</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lstm_layers</span><span class=\"o\">-</span><span class=\"mi\">1</span>\n                                                                      <span class=\"k\">else</span> <span class=\"kc\">False</span><span class=\"p\">)</span>\\\n                                                    <span class=\"p\">(</span><span class=\"n\">x_rnn</span><span class=\"p\">)</span>\n\n                    <span class=\"n\">H</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">x_rnn</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">station_number</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lstm_units</span><span class=\"p\">])</span>\n\n                    <span class=\"n\">outputs</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">H</span><span class=\"p\">)</span>\n\n            <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_sum</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># external dims</span>\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">external_input</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span><span class=\"p\">])</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;external_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">external_input</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"n\">external_dense</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">dense</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">external_input</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n                <span class=\"n\">external_dense</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">external_dense</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">]),</span>\n                                         <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">)[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n                <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">external_dense</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">dense</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"n\">loss</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">prediction</span> <span class=\"o\">-</span> <span class=\"n\">target</span><span class=\"p\">)))</span>\n\n            <span class=\"n\">train_operation</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">AdamOptimizer</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">minimize</span><span class=\"p\">(</span><span class=\"n\">loss</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># record output</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">prediction</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">loss</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"c1\"># record train operation</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">train_operation</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">ST_MGCN</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">(</span><span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"n\">init_vars</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"n\">max_to_keep</span><span class=\"p\">)</span></div>\n\n    <span class=\"c1\"># Step 1 : Define your &#39;_get_feed_dict function‘, map your input to the tf-model</span>\n    <span class=\"k\">def</span> <span class=\"nf\">_get_feed_dict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">traffic_flow</span><span class=\"p\">,</span> <span class=\"n\">laplace_matrix</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">external_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"n\">feed_dict</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n            <span class=\"s1\">&#39;traffic_flow&#39;</span><span class=\"p\">:</span> <span class=\"n\">traffic_flow</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;laplace_matrix&#39;</span><span class=\"p\">:</span> <span class=\"n\">laplace_matrix</span><span class=\"p\">,</span>\n        <span class=\"p\">}</span>\n        <span class=\"k\">if</span> <span class=\"n\">target</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">target</span>\n        <span class=\"k\">if</span> <span class=\"n\">external_feature</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;external_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">external_feature</span>\n        <span class=\"k\">return</span> <span class=\"n\">feed_dict</span></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model/ST_ResNet.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model.ST_ResNet &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model.ST_ResNet</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">..model_unit</span> <span class=\"k\">import</span> <span class=\"n\">BaseModel</span>\n\n\n<div class=\"viewcode-block\" id=\"ST_ResNet\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.ST_ResNet.ST_ResNet\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">ST_ResNet</span><span class=\"p\">(</span><span class=\"n\">BaseModel</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;ST-ResNet is a deep-learning model with an end-to-end structure</span>\n<span class=\"sd\">    based on unique properties of spatio-temporal data making use of convolution and residual units.</span>\n\n<span class=\"sd\">    Reference: `Deep Spatio-Temporal Residual Networks for Citywide Crowd Flows Prediction (Junbo Zhang et al., 2016)</span>\n<span class=\"sd\">    &lt;https://arxiv.org/pdf/1610.00081.pdf&gt;`_.</span>\n\n<span class=\"sd\">    Args:</span>\n<span class=\"sd\">        width (int): The width of grid data.</span>\n<span class=\"sd\">        height (int): The height of grid data.</span>\n<span class=\"sd\">        externai_dim (int): Number of dimensions of external data.</span>\n<span class=\"sd\">        closeness_len (int): The length of closeness data history. The former consecutive ``closeness_len`` time slots</span>\n<span class=\"sd\">            of data will be used as closeness history.</span>\n<span class=\"sd\">        period_len (int): The length of period data history. The data of exact same time slots in former consecutive</span>\n<span class=\"sd\">            ``period_len`` days will be used as period history.</span>\n<span class=\"sd\">        trend_len (int): The length of trend data history. The data of exact same time slots in former consecutive</span>\n<span class=\"sd\">            ``trend_len`` weeks (every seven days) will be used as trend history.</span>\n<span class=\"sd\">        num_residual_unit (int): Number of residual units. Default: 4</span>\n<span class=\"sd\">        kernel_size (int): Kernel size in Convolutional neural networks. Default: 3</span>\n<span class=\"sd\">        lr (float): Learning rate. Default: 1e-5</span>\n<span class=\"sd\">        code_version (str): Current version of this model code.</span>\n<span class=\"sd\">        model_dir (str): The directory to store model files. Default:&#39;model_dir&#39;</span>\n<span class=\"sd\">        conv_filters (int):  the Number of filters in the convolution. Default: 64</span>\n<span class=\"sd\">        gpu_device (str): To specify the GPU to use. Default: &#39;0&#39;</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 <span class=\"n\">width</span><span class=\"p\">,</span>\n                 <span class=\"n\">height</span><span class=\"p\">,</span>\n                 <span class=\"n\">external_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">closeness_len</span><span class=\"p\">,</span>\n                 <span class=\"n\">period_len</span><span class=\"p\">,</span>\n                 <span class=\"n\">trend_len</span><span class=\"p\">,</span>\n                 <span class=\"n\">num_residual_unit</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span>\n                 <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span>\n                 <span class=\"n\">lr</span><span class=\"o\">=</span><span class=\"mf\">5e-5</span><span class=\"p\">,</span>\n                 <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;model_dir&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"s1\">&#39;QuickStart&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">conv_filters</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span>\n                 <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">):</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">ST_ResNet</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"n\">code_version</span><span class=\"p\">,</span> <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"n\">model_dir</span><span class=\"p\">,</span> <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"n\">gpu_device</span><span class=\"p\">)</span>\n        \n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span> <span class=\"o\">=</span> <span class=\"n\">width</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span> <span class=\"o\">=</span> <span class=\"n\">height</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"o\">=</span> <span class=\"n\">closeness_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"o\">=</span> <span class=\"n\">period_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"o\">=</span> <span class=\"n\">trend_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_conv_filters</span> <span class=\"o\">=</span> <span class=\"n\">conv_filters</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span> <span class=\"o\">=</span> <span class=\"n\">kernel_size</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">=</span> <span class=\"n\">external_dim</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_residual_unit</span> <span class=\"o\">=</span> <span class=\"n\">num_residual_unit</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span> <span class=\"o\">=</span> <span class=\"n\">lr</span>\n\n<div class=\"viewcode-block\" id=\"ST_ResNet.build\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.ST_ResNet.ST_ResNet.build\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n\n            <span class=\"n\">target_conf</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">c_conf</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;c&#39;</span><span class=\"p\">)</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;closeness_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">c_conf</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"n\">target_conf</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">c_conf</span><span class=\"p\">)</span>\n\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">p_conf</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;p&#39;</span><span class=\"p\">)</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;period_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">p_conf</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"n\">target_conf</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">p_conf</span><span class=\"p\">)</span>\n\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">t_conf</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;t&#39;</span><span class=\"p\">)</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;trend_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t_conf</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"n\">target_conf</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">t_conf</span><span class=\"p\">)</span>\n\n            <span class=\"n\">target</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">)</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">target</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            <span class=\"k\">for</span> <span class=\"n\">conf</span> <span class=\"ow\">in</span> <span class=\"n\">target_conf</span><span class=\"p\">:</span>\n\n                <span class=\"n\">residual_input</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">conf</span><span class=\"p\">,</span> <span class=\"n\">filters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_conv_filters</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">],</span>\n                                                  <span class=\"n\">padding</span><span class=\"o\">=</span><span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">,</span> <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">relu</span><span class=\"p\">)</span>\n\n                <span class=\"k\">def</span> <span class=\"nf\">residual_unit</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">):</span>\n                    <span class=\"n\">residual_output</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">relu</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)</span>\n                    <span class=\"n\">residual_output</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">residual_output</span><span class=\"p\">,</span> <span class=\"n\">filters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_conv_filters</span><span class=\"p\">,</span>\n                                                       <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">],</span> <span class=\"n\">padding</span><span class=\"o\">=</span><span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">)</span>\n                    <span class=\"n\">residual_output</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">relu</span><span class=\"p\">(</span><span class=\"n\">residual_output</span><span class=\"p\">)</span>\n                    <span class=\"n\">residual_output</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">residual_output</span><span class=\"p\">,</span> <span class=\"n\">filters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_conv_filters</span><span class=\"p\">,</span>\n                                                       <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">],</span> <span class=\"n\">padding</span><span class=\"o\">=</span><span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">)</span>\n                    <span class=\"k\">return</span> <span class=\"n\">residual_output</span> <span class=\"o\">+</span> <span class=\"n\">x</span>\n\n                <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_residual_unit</span><span class=\"p\">):</span>\n                    <span class=\"n\">residual_input</span> <span class=\"o\">=</span> <span class=\"n\">residual_unit</span><span class=\"p\">(</span><span class=\"n\">residual_input</span><span class=\"p\">)</span>\n\n                <span class=\"n\">outputs</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">conv2d</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">relu</span><span class=\"p\">(</span><span class=\"n\">residual_input</span><span class=\"p\">),</span> <span class=\"n\">filters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_conv_filters</span><span class=\"p\">,</span>\n                                                <span class=\"n\">kernel_size</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_kernel_size</span><span class=\"p\">],</span> <span class=\"n\">padding</span><span class=\"o\">=</span><span class=\"s1\">&#39;SAME&#39;</span><span class=\"p\">))</span>\n\n            <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n                <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"n\">fusion_weight</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">random_normal</span><span class=\"p\">([</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">),</span> <span class=\"p\">]))</span>\n                <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">)):</span>\n                    <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">fusion_weight</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span>\n                <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_sum</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># external dims</span>\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"n\">external_input</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span><span class=\"p\">])</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;external_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">external_input</span><span class=\"o\">.</span><span class=\"n\">name</span>\n                <span class=\"n\">external_dense</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">dense</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">external_input</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n                <span class=\"n\">external_dense</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">external_dense</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">]),</span>\n                                         <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_height</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_width</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n                <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">external_dense</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">dense</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">,</span> <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">sigmoid</span><span class=\"p\">)</span>\n\n            <span class=\"n\">loss</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">x</span> <span class=\"o\">-</span> <span class=\"n\">target</span><span class=\"p\">)),</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">)</span>\n            <span class=\"n\">train_op</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">AdamOptimizer</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_lr</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">minimize</span><span class=\"p\">(</span><span class=\"n\">loss</span><span class=\"p\">)</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">x</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">loss</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">train_op</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">ST_ResNet</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">()</span></div>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_get_feed_dict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">closeness_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">period_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">trend_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                       <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">external_feature</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&#39;&#39;&#39;</span>\n<span class=\"sd\">        The method to get feet dict for tensorflow model.</span>\n\n<span class=\"sd\">        Users may modify this method according to the format of input.</span>\n\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            closeness_feature (np.ndarray or ``None``): The closeness history data.</span>\n<span class=\"sd\">                If type is np.ndarray, its shape is [time_slot_num, height, width, closeness_len].</span>\n<span class=\"sd\">            period_feature (np.ndarray or ``None``): The period history data.</span>\n<span class=\"sd\">                If type is np.ndarray, its shape is [time_slot_num, height, width, period_len].</span>\n<span class=\"sd\">            trend_feature (np.ndarray or ``None``): The trend history data.</span>\n<span class=\"sd\">                If type is np.ndarray, its shape is [time_slot_num, height, width, trend_len].</span>\n<span class=\"sd\">            target (np.ndarray or ``None``): The target value data.</span>\n<span class=\"sd\">                If type is np.ndarray, its shape is [time_slot_num, height, width, 1].</span>\n<span class=\"sd\">            external_feature (np.ndarray or ``None``): The external feature data.</span>\n<span class=\"sd\">                If type is np.ndaaray, its shape is [time_slot_num, feature_num].</span>\n<span class=\"sd\">        &#39;&#39;&#39;</span>\n        <span class=\"n\">feed_dict</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n        <span class=\"k\">if</span> <span class=\"n\">target</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;target&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">target</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_external_dim</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;external_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">external_feature</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_closeness_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;closeness_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">closeness_feature</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_period_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;period_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">period_feature</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_trend_len</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">feed_dict</span><span class=\"p\">[</span><span class=\"s1\">&#39;trend_feature&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">trend_feature</span>\n        <span class=\"k\">return</span> <span class=\"n\">feed_dict</span></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model/XGBoost.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model.XGBoost &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model.XGBoost</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">xgboost</span> <span class=\"k\">as</span> <span class=\"nn\">xgb</span>\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n\n<div class=\"viewcode-block\" id=\"XGBoost\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.XGBoost.XGBoost\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">XGBoost</span><span class=\"p\">():</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">n_estimators</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"n\">max_depth</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"n\">verbosity</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">objective</span><span class=\"o\">=</span><span class=\"s1\">&#39;reg:squarederror&#39;</span><span class=\"p\">,</span> <span class=\"n\">eval_metric</span><span class=\"o\">=</span><span class=\"s1\">&#39;rmse&#39;</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;XGBoost is an optimized distributed gradient boosting machine learning algorithm.</span>\n\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            n_estimators (int): Number of boosting iterations. Default: 10</span>\n<span class=\"sd\">            max_depth (int): Maximum tree depth for base learners. Default: 5</span>\n<span class=\"sd\">            verbosity (int): The degree of verbosity. Valid values are 0 (silent) - 3 (debug). Default: 0</span>\n<span class=\"sd\">            objective (string or callable):</span>\n<span class=\"sd\">                Specify the learning task and the corresponding learning objective or</span>\n<span class=\"sd\">                a custom objective function to be used. Default: ``&#39;reg:squarederror&#39;``</span>\n<span class=\"sd\">            eval_metric (str, list of str, or callable, optional):</span>\n<span class=\"sd\">                If a str, should be a built-in evaluation metric to use. See more in</span>\n<span class=\"sd\">                `API Reference of XGBoost Library &lt;https://xgboost.readthedocs.io/en/latest/python/python_api.html&gt;`_.</span>\n<span class=\"sd\">                Default: ``&#39;rmse&#39;``</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">param</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n            <span class=\"s1\">&#39;max_depth&#39;</span><span class=\"p\">:</span> <span class=\"n\">max_depth</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;verbosity &#39;</span><span class=\"p\">:</span> <span class=\"n\">verbosity</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;objective&#39;</span><span class=\"p\">:</span> <span class=\"n\">objective</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;eval_metric&#39;</span><span class=\"p\">:</span> <span class=\"n\">eval_metric</span>\n        <span class=\"p\">}</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_estimators</span> <span class=\"o\">=</span> <span class=\"n\">n_estimators</span>\n\n<div class=\"viewcode-block\" id=\"XGBoost.fit\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.XGBoost.XGBoost.fit\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">fit</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">):</span>\n        <span class=\"n\">train_matrix</span> <span class=\"o\">=</span> <span class=\"n\">xgb</span><span class=\"o\">.</span><span class=\"n\">DMatrix</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">label</span><span class=\"o\">=</span><span class=\"n\">y</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">xgb</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">param</span><span class=\"p\">,</span> <span class=\"n\">train_matrix</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_estimators</span><span class=\"p\">)</span></div>\n\n<div class=\"viewcode-block\" id=\"XGBoost.predict\"><a class=\"viewcode-back\" href=\"../../../UCTB.model.html#UCTB.model.XGBoost.XGBoost.predict\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"n\">test_matrix</span> <span class=\"o\">=</span> <span class=\"n\">xgb</span><span class=\"o\">.</span><span class=\"n\">DMatrix</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">test_matrix</span><span class=\"p\">)</span></div></div>\n\n\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model_unit/BaseModel.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model_unit.BaseModel &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model_unit.BaseModel</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">os</span>\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">shutil</span>\n<span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">tensorboard.backend.event_processing</span> <span class=\"k\">import</span> <span class=\"n\">event_accumulator</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">..train.MiniBatchTrain</span> <span class=\"k\">import</span> <span class=\"n\">MiniBatchFeedDict</span>\n<span class=\"kn\">from</span> <span class=\"nn\">..preprocess.preprocessor</span> <span class=\"k\">import</span> <span class=\"n\">SplitData</span>\n<span class=\"kn\">from</span> <span class=\"nn\">..train.EarlyStopping</span> <span class=\"k\">import</span> <span class=\"o\">*</span>\n\n\n<div class=\"viewcode-block\" id=\"BaseModel\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">BaseModel</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;BaseModel is the base class for many models, such as STMeta, ST-MGCN and ST_ResNet,</span>\n<span class=\"sd\">        you can also build your own model using this class. More information can be found in tutorial.</span>\n<span class=\"sd\">    Args:</span>\n<span class=\"sd\">        code_version: Current version of this model code, which will be used as filename for saving the model.</span>\n<span class=\"sd\">        model_dir: The directory to store model files. Default:&#39;model_dir&#39;.</span>\n<span class=\"sd\">        gpu_device: To specify the GPU to use. Default: &#39;0&#39;.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">code_version</span><span class=\"p\">,</span> <span class=\"n\">model_dir</span><span class=\"p\">,</span> <span class=\"n\">gpu_device</span><span class=\"p\">):</span>\n\n        <span class=\"c1\"># model input and output</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_variable_init</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_saver</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_code_version</span> <span class=\"o\">=</span> <span class=\"n\">code_version</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_model_dir</span> <span class=\"o\">=</span> <span class=\"n\">model_dir</span>\n\n        <span class=\"c1\"># TF Graph</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Graph</span><span class=\"p\">()</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_converged</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_log_dir</span> <span class=\"o\">=</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_model_dir</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_code_version</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_global_step</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_summary</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_summary_writer</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">summary</span><span class=\"o\">.</span><span class=\"n\">FileWriter</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_log_dir</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trainable_vars</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n\n        <span class=\"c1\"># TF Session</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_GPU_DEVICE</span> <span class=\"o\">=</span> <span class=\"n\">gpu_device</span>\n        <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">environ</span><span class=\"p\">[</span><span class=\"s2\">&quot;CUDA_DEVICE_ORDER&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;PCI_BUS_ID&quot;</span>\n        <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">environ</span><span class=\"p\">[</span><span class=\"s2\">&quot;CUDA_VISIBLE_DEVICES&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_GPU_DEVICE</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_config</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">ConfigProto</span><span class=\"p\">()</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_config</span><span class=\"o\">.</span><span class=\"n\">gpu_options</span><span class=\"o\">.</span><span class=\"n\">allow_growth</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_session</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Session</span><span class=\"p\">(</span><span class=\"n\">graph</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"p\">,</span> <span class=\"n\">config</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_config</span><span class=\"p\">)</span>\n\n<div class=\"viewcode-block\" id=\"BaseModel.build\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.build\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Args</span>\n<span class=\"sd\">            init_vars(bool): auto init the parameters if set to True, else no parameters will be initialized.</span>\n<span class=\"sd\">            max_to_keep: max file to keep, which equals to max_to_keep in tf.train.Saver.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n            <span class=\"c1\">####################################################################</span>\n            <span class=\"c1\"># Add summary, variable_init and summary</span>\n            <span class=\"c1\"># The variable name of them are fixed</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">trainable_vars</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">([</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">prod</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">as_list</span><span class=\"p\">())</span> <span class=\"k\">for</span> <span class=\"n\">v</span> <span class=\"ow\">in</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">trainable_variables</span><span class=\"p\">()])</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_saver</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">Saver</span><span class=\"p\">(</span><span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"n\">max_to_keep</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_variable_init</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">global_variables_initializer</span><span class=\"p\">()</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_summary</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_summary_histogram</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"c1\">####################################################################</span>\n        <span class=\"k\">if</span> <span class=\"n\">init_vars</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_session</span><span class=\"o\">.</span><span class=\"n\">run</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_variable_init</span><span class=\"p\">)</span></div>\n\n<div class=\"viewcode-block\" id=\"BaseModel.add_summary\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.add_summary\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">add_summary</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">global_step</span><span class=\"p\">):</span>\n        <span class=\"n\">value_record</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Summary</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Summary</span><span class=\"o\">.</span><span class=\"n\">Value</span><span class=\"p\">(</span><span class=\"n\">tag</span><span class=\"o\">=</span><span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">simple_value</span><span class=\"o\">=</span><span class=\"n\">value</span><span class=\"p\">)])</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_summary_writer</span><span class=\"o\">.</span><span class=\"n\">add_summary</span><span class=\"p\">(</span><span class=\"n\">value_record</span><span class=\"p\">,</span> <span class=\"n\">global_step</span><span class=\"p\">)</span></div>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_summary_histogram</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n            <span class=\"k\">for</span> <span class=\"n\">var</span> <span class=\"ow\">in</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">trainable_variables</span><span class=\"p\">():</span>\n                <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">summary</span><span class=\"o\">.</span><span class=\"n\">histogram</span><span class=\"p\">(</span><span class=\"n\">var</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">var</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_summary_writer</span><span class=\"o\">.</span><span class=\"n\">add_graph</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">summary</span><span class=\"o\">.</span><span class=\"n\">merge_all</span><span class=\"p\">()</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_run</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">feed_dict</span><span class=\"p\">,</span> <span class=\"n\">output_names</span><span class=\"p\">,</span> <span class=\"n\">op_names</span><span class=\"p\">):</span>\n        <span class=\"n\">feed_dict_tf</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n        <span class=\"k\">for</span> <span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">value</span> <span class=\"ow\">in</span> <span class=\"n\">feed_dict</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n            <span class=\"k\">if</span> <span class=\"n\">value</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n                <span class=\"n\">feed_dict_tf</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">get_tensor_by_name</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">])]</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n\n        <span class=\"n\">output_tensor_list</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">get_tensor_by_name</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">])</span> <span class=\"k\">for</span> <span class=\"n\">name</span> <span class=\"ow\">in</span> <span class=\"n\">output_names</span><span class=\"p\">]</span>\n        <span class=\"n\">output_tensor_list</span> <span class=\"o\">+=</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">get_operation_by_name</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">])</span> <span class=\"k\">for</span> <span class=\"n\">name</span> <span class=\"ow\">in</span> <span class=\"n\">op_names</span><span class=\"p\">]</span>\n\n        <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_session</span><span class=\"o\">.</span><span class=\"n\">run</span><span class=\"p\">(</span><span class=\"n\">output_tensor_list</span><span class=\"p\">,</span> <span class=\"n\">feed_dict</span><span class=\"o\">=</span><span class=\"n\">feed_dict_tf</span><span class=\"p\">)</span>\n\n        <span class=\"k\">return</span> <span class=\"p\">{</span><span class=\"n\">output_names</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]:</span> <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">output_names</span><span class=\"p\">))}</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_get_feed_dict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">kwargs</span>\n\n<div class=\"viewcode-block\" id=\"BaseModel.fit\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.fit\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">fit</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">sequence_length</span><span class=\"p\">,</span> <span class=\"n\">output_names</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">,</span> <span class=\"p\">),</span> <span class=\"n\">op_names</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">,</span> <span class=\"p\">),</span> <span class=\"n\">evaluate_loss_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">,</span>\n            <span class=\"n\">batch_size</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span> <span class=\"n\">max_epoch</span><span class=\"o\">=</span><span class=\"mi\">10000</span><span class=\"p\">,</span> <span class=\"n\">validate_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span> <span class=\"n\">shuffle_data</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n            <span class=\"n\">early_stop_method</span><span class=\"o\">=</span><span class=\"s1\">&#39;t-test&#39;</span><span class=\"p\">,</span> <span class=\"n\">early_stop_length</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"n\">early_stop_patience</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span>\n            <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">save_model</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">save_model_name</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">auto_load_model</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n            <span class=\"n\">return_outputs</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n\n        <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            sequence_length: int, the sequence length which is use in mini-batch training</span>\n<span class=\"sd\">            output_names: list, [output_tensor1_name, output_tensor1_name, ...]</span>\n<span class=\"sd\">            op_names: list, [operation1_name, operation2_name, ...]</span>\n<span class=\"sd\">            evaluate_loss_name: str, should be on of the output_names, evaluate_loss_name was use in</span>\n<span class=\"sd\">                                       early-stopping</span>\n<span class=\"sd\">            batch_size: int, default 64, batch size</span>\n<span class=\"sd\">            max_epoch: int, default 10000, max number of epochs</span>\n<span class=\"sd\">            validate_ratio: float, default 0.1, the ration of data that will be used as validation dataset</span>\n<span class=\"sd\">            shuffle_data: bool, default True, whether shuffle data in mini-batch train</span>\n<span class=\"sd\">            early_stop_method: should be &#39;t-test&#39; or &#39;naive&#39;, both method are explained in train.EarlyStopping</span>\n<span class=\"sd\">            early_stop_length: int, must provide when early_stop_method=&#39;t-test&#39;</span>\n<span class=\"sd\">            early_stop_patience: int, must provide when early_stop_method=&#39;naive&#39;</span>\n<span class=\"sd\">            verbose: Bool, flag to print training information or not</span>\n<span class=\"sd\">            save_model: Bool, flog to save model or not</span>\n<span class=\"sd\">            save_model_name: String, filename for saving the model, which will overwrite the code_version.</span>\n<span class=\"sd\">            auto_load_model: Bool, the &quot;fit&quot; function will automatically load the model from disk, if exists,</span>\n<span class=\"sd\">                before the training. Set to False to disable the auto-loading.</span>\n<span class=\"sd\">            return_outputs: Bool, set True to return the training log, otherwise nothing will be returned</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">auto_load_model</span><span class=\"p\">:</span>\n            <span class=\"k\">try</span><span class=\"p\">:</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_code_version</span><span class=\"p\">)</span>\n                <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Found model in disk&#39;</span><span class=\"p\">)</span>\n                <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_converged</span><span class=\"p\">:</span>\n                    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Model converged, stop training&#39;</span><span class=\"p\">)</span>\n                    <span class=\"k\">return</span>\n                <span class=\"k\">else</span><span class=\"p\">:</span>\n                    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Model not converged, continue at step&#39;</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_global_step</span><span class=\"p\">)</span>\n                    <span class=\"n\">start_epoch</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_global_step</span>\n            <span class=\"k\">except</span> <span class=\"ne\">FileNotFoundError</span><span class=\"p\">:</span>\n                <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;No model found, start training&#39;</span><span class=\"p\">)</span>\n                <span class=\"n\">start_epoch</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">start_epoch</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n            <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Not loading model from disk&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"mi\">0</span> <span class=\"o\">&lt;</span> <span class=\"n\">validate_ratio</span> <span class=\"o\">&lt;</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;validate_ratio should between (0, 1), given&#39;</span><span class=\"p\">,</span> <span class=\"n\">validate_ratio</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">evaluate_loss_name</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">output_names</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;evaluate_loss_name not shown in&#39;</span><span class=\"p\">,</span> <span class=\"n\">output_names</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">op_names</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;No operation given&#39;</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Running Operation&#39;</span><span class=\"p\">,</span> <span class=\"n\">op_names</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Get feed_dict</span>\n        <span class=\"n\">feed_dict</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_get_feed_dict</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Split data into train-data and validation data</span>\n        <span class=\"n\">train_feed_dict</span><span class=\"p\">,</span> <span class=\"n\">val_feed_dict</span> <span class=\"o\">=</span> <span class=\"n\">SplitData</span><span class=\"o\">.</span><span class=\"n\">split_feed_dict</span><span class=\"p\">(</span><span class=\"n\">feed_dict</span><span class=\"p\">,</span>\n                                                                   <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">sequence_length</span><span class=\"p\">,</span>\n                                                                   <span class=\"n\">ratio_list</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">1</span> <span class=\"o\">-</span> <span class=\"n\">validate_ratio</span><span class=\"p\">,</span> <span class=\"n\">validate_ratio</span><span class=\"p\">])</span>\n\n        <span class=\"n\">train_sequence_length</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">sequence_length</span><span class=\"o\">*</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"o\">-</span><span class=\"n\">validate_ratio</span><span class=\"p\">))</span>\n        <span class=\"n\">val_sequence_len</span> <span class=\"o\">=</span> <span class=\"n\">sequence_length</span> <span class=\"o\">-</span> <span class=\"n\">train_sequence_length</span>\n\n        <span class=\"c1\"># build mini-batch data source on train-data</span>\n        <span class=\"n\">train_dict_mini_batch</span> <span class=\"o\">=</span> <span class=\"n\">MiniBatchFeedDict</span><span class=\"p\">(</span><span class=\"n\">feed_dict</span><span class=\"o\">=</span><span class=\"n\">train_feed_dict</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">train_sequence_length</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">batch_size</span><span class=\"o\">=</span><span class=\"n\">batch_size</span><span class=\"p\">,</span>\n                                                  <span class=\"n\">shuffle</span><span class=\"o\">=</span><span class=\"n\">shuffle_data</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># record the best result of &quot;evaluate_loss_name&quot;</span>\n        <span class=\"n\">best_record</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"c1\"># init early stopping object</span>\n        <span class=\"k\">if</span> <span class=\"n\">early_stop_method</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;t-test&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">early_stop</span> <span class=\"o\">=</span> <span class=\"n\">EarlyStoppingTTest</span><span class=\"p\">(</span><span class=\"n\">length</span><span class=\"o\">=</span><span class=\"n\">early_stop_length</span><span class=\"p\">,</span> <span class=\"n\">p_value_threshold</span><span class=\"o\">=</span><span class=\"n\">early_stop_patience</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">early_stop</span> <span class=\"o\">=</span> <span class=\"n\">EarlyStopping</span><span class=\"p\">(</span><span class=\"n\">patience</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">early_stop_patience</span><span class=\"p\">))</span>\n\n        <span class=\"c1\"># start mini-batch training</span>\n        <span class=\"n\">summary_output</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"k\">for</span> <span class=\"n\">epoch</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">start_epoch</span><span class=\"p\">,</span> <span class=\"n\">max_epoch</span><span class=\"p\">):</span>\n            <span class=\"n\">train_output_list</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">train_dict_mini_batch</span><span class=\"o\">.</span><span class=\"n\">num_batch</span><span class=\"p\">):</span>\n                <span class=\"c1\"># train</span>\n                <span class=\"n\">train_output</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_run</span><span class=\"p\">(</span><span class=\"n\">feed_dict</span><span class=\"o\">=</span><span class=\"n\">train_dict_mini_batch</span><span class=\"o\">.</span><span class=\"n\">get_batch</span><span class=\"p\">(),</span>\n                                         <span class=\"n\">output_names</span><span class=\"o\">=</span><span class=\"n\">output_names</span><span class=\"p\">,</span>\n                                         <span class=\"n\">op_names</span><span class=\"o\">=</span><span class=\"n\">op_names</span><span class=\"p\">)</span>\n                <span class=\"n\">train_output_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">train_output</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># validation</span>\n            <span class=\"n\">val_output</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">val_feed_dict</span><span class=\"p\">,</span> <span class=\"n\">output_names</span><span class=\"o\">=</span><span class=\"n\">output_names</span><span class=\"p\">,</span>\n                                      <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">val_sequence_len</span><span class=\"p\">,</span>\n                                      <span class=\"n\">cache_volume</span><span class=\"o\">=</span><span class=\"n\">batch_size</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># Here we only care about the evaluate_loss_value</span>\n            <span class=\"n\">evaluate_loss_value</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"n\">val_output</span><span class=\"p\">[</span><span class=\"n\">evaluate_loss_name</span><span class=\"p\">])</span>\n\n            <span class=\"c1\"># Add Summary</span>\n            <span class=\"n\">tmp_summary</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n            <span class=\"k\">for</span> <span class=\"n\">name</span> <span class=\"ow\">in</span> <span class=\"n\">output_names</span><span class=\"p\">:</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_summary</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;train_&#39;</span> <span class=\"o\">+</span> <span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">value</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">train_output_list</span><span class=\"p\">]),</span>\n                                 <span class=\"n\">global_step</span><span class=\"o\">=</span><span class=\"n\">epoch</span><span class=\"p\">)</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_summary</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;val_&#39;</span> <span class=\"o\">+</span> <span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">value</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"n\">val_output</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">]),</span> <span class=\"n\">global_step</span><span class=\"o\">=</span><span class=\"n\">epoch</span><span class=\"p\">)</span>\n                <span class=\"c1\"># print training messages</span>\n                <span class=\"k\">if</span> <span class=\"n\">verbose</span><span class=\"p\">:</span>\n                    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Epoch </span><span class=\"si\">%s</span><span class=\"s1\">:&#39;</span> <span class=\"o\">%</span> <span class=\"n\">epoch</span><span class=\"p\">,</span>\n                          <span class=\"s1\">&#39;train_&#39;</span> <span class=\"o\">+</span> <span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">train_output_list</span><span class=\"p\">]),</span>\n                          <span class=\"s1\">&#39;val_&#39;</span> <span class=\"o\">+</span> <span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"n\">val_output</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">]))</span>\n                    <span class=\"n\">tmp_summary</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_&#39;</span> <span class=\"o\">+</span> <span class=\"n\">name</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">train_output_list</span><span class=\"p\">])</span>\n                    <span class=\"n\">tmp_summary</span><span class=\"p\">[</span><span class=\"s1\">&#39;val_&#39;</span> <span class=\"o\">+</span> <span class=\"n\">name</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"n\">val_output</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">])</span>\n            <span class=\"n\">summary_output</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tmp_summary</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># manual_summary the histograms</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">manual_summary</span><span class=\"p\">(</span><span class=\"n\">global_step</span><span class=\"o\">=</span><span class=\"n\">epoch</span><span class=\"p\">)</span>\n\n            <span class=\"k\">if</span> <span class=\"n\">early_stop</span><span class=\"o\">.</span><span class=\"n\">stop</span><span class=\"p\">(</span><span class=\"n\">evaluate_loss_value</span><span class=\"p\">):</span>\n                <span class=\"k\">if</span> <span class=\"n\">save_model</span><span class=\"p\">:</span>\n                    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_log</span><span class=\"p\">(</span><span class=\"s1\">&#39;Converged&#39;</span><span class=\"p\">)</span>\n                <span class=\"k\">break</span>\n\n            <span class=\"c1\"># save the model if evaluate_loss_value is smaller than best_record</span>\n            <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">best_record</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span> <span class=\"ow\">or</span> <span class=\"n\">evaluate_loss_value</span> <span class=\"o\">&lt;</span> <span class=\"n\">best_record</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">save_model</span><span class=\"p\">:</span>\n                <span class=\"n\">best_record</span> <span class=\"o\">=</span> <span class=\"n\">evaluate_loss_value</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">save_model_name</span> <span class=\"ow\">or</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_code_version</span><span class=\"p\">,</span> <span class=\"n\">epoch</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">return_outputs</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">summary_output</span></div>\n\n<div class=\"viewcode-block\" id=\"BaseModel.predict\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.predict\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">sequence_length</span><span class=\"p\">,</span> <span class=\"n\">output_names</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">,</span> <span class=\"p\">),</span> <span class=\"n\">cache_volume</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n\n        <span class=\"sd\">&#39;&#39;&#39;</span>\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            output_names: list, [output_tensor_name1, output_tensor_name2, ...]</span>\n<span class=\"sd\">            sequence_length: int, the length of sequence, which is use in mini-batch training</span>\n<span class=\"sd\">            cache_volume: int, default 64, we need to set cache_volume if the cache can not hold</span>\n<span class=\"sd\">                                 the whole validation dataset</span>\n<span class=\"sd\">            :return: outputs_dict: dict, like {output_tensor1_name: output_tensor1_value, ...}</span>\n<span class=\"sd\">        &#39;&#39;&#39;</span>\n\n        <span class=\"c1\"># Get feed_dict</span>\n        <span class=\"n\">feed_dict</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_get_feed_dict</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">cache_volume</span> <span class=\"ow\">and</span> <span class=\"n\">sequence_length</span><span class=\"p\">:</span>\n            <span class=\"c1\"># storing the prediction result</span>\n            <span class=\"n\">outputs_list</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            <span class=\"n\">outputs_dict</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n            <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">sequence_length</span><span class=\"p\">,</span> <span class=\"n\">cache_volume</span><span class=\"p\">):</span>\n                <span class=\"n\">tmp_output</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_run</span><span class=\"p\">({</span><span class=\"n\">key</span><span class=\"p\">:</span> <span class=\"n\">value</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">:</span><span class=\"n\">i</span><span class=\"o\">+</span><span class=\"n\">cache_volume</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"n\">sequence_length</span> <span class=\"k\">else</span> <span class=\"n\">value</span>\n                                        <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span> <span class=\"ow\">in</span> <span class=\"n\">feed_dict</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">()},</span>\n                                       <span class=\"n\">output_names</span><span class=\"p\">,</span> <span class=\"n\">op_names</span><span class=\"o\">=</span><span class=\"p\">[])</span>\n                <span class=\"n\">outputs_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tmp_output</span><span class=\"p\">)</span>\n            <span class=\"c1\"># stack the output together</span>\n            <span class=\"k\">for</span> <span class=\"n\">key</span> <span class=\"ow\">in</span> <span class=\"n\">outputs_list</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span>\n                <span class=\"n\">outputs_dict</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">vstack</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">outputs_list</span><span class=\"p\">])</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">outputs_dict</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_run</span><span class=\"p\">(</span><span class=\"n\">feed_dict</span><span class=\"p\">,</span> <span class=\"n\">output_names</span><span class=\"p\">,</span> <span class=\"n\">op_names</span><span class=\"o\">=</span><span class=\"p\">[])</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">outputs_dict</span></div>\n\n<div class=\"viewcode-block\" id=\"BaseModel.manual_summary\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.manual_summary\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">manual_summary</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">global_step</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_summary_writer</span><span class=\"o\">.</span><span class=\"n\">add_summary</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_session</span><span class=\"o\">.</span><span class=\"n\">run</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">get_tensor_by_name</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_summary</span><span class=\"p\">)),</span>\n                                         <span class=\"n\">global_step</span><span class=\"o\">=</span><span class=\"n\">global_step</span><span class=\"p\">)</span></div>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_log</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">text</span><span class=\"p\">):</span>\n        <span class=\"n\">save_dir_subscript</span> <span class=\"o\">=</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_log_dir</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_code_version</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">isdir</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"kc\">False</span><span class=\"p\">:</span>\n            <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">makedirs</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">)</span>\n        <span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">,</span> <span class=\"s1\">&#39;log.txt&#39;</span><span class=\"p\">),</span> <span class=\"s1\">&#39;a+&#39;</span><span class=\"p\">,</span> <span class=\"n\">encoding</span><span class=\"o\">=</span><span class=\"s1\">&#39;utf-8&#39;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">f</span><span class=\"p\">:</span>\n            <span class=\"n\">f</span><span class=\"o\">.</span><span class=\"n\">write</span><span class=\"p\">(</span><span class=\"n\">text</span> <span class=\"o\">+</span> <span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_get_log</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">save_dir_subscript</span> <span class=\"o\">=</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_log_dir</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_code_version</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">isfile</span><span class=\"p\">(</span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">,</span> <span class=\"s1\">&#39;log.txt&#39;</span><span class=\"p\">)):</span>\n            <span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">,</span> <span class=\"s1\">&#39;log.txt&#39;</span><span class=\"p\">),</span> <span class=\"s1\">&#39;r&#39;</span><span class=\"p\">,</span> <span class=\"n\">encoding</span><span class=\"o\">=</span><span class=\"s1\">&#39;utf-8&#39;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">f</span><span class=\"p\">:</span>\n                <span class=\"k\">return</span> <span class=\"p\">[</span><span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">strip</span><span class=\"p\">(</span><span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">f</span><span class=\"o\">.</span><span class=\"n\">readlines</span><span class=\"p\">()]</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"p\">[]</span>\n\n<div class=\"viewcode-block\" id=\"BaseModel.save\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.save\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">save</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">subscript</span><span class=\"p\">,</span> <span class=\"n\">global_step</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            subscript: String, subscript will be appended to the code version as the model filename,</span>\n<span class=\"sd\">                and save the corresponding model using this filename</span>\n<span class=\"sd\">            global_step: Int, current training steps</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">save_dir_subscript</span> <span class=\"o\">=</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_log_dir</span><span class=\"p\">,</span> <span class=\"n\">subscript</span><span class=\"p\">)</span>\n        <span class=\"c1\"># delete if exist</span>\n        <span class=\"c1\"># if os.path.isdir(save_dir_subscript):</span>\n        <span class=\"c1\">#     shutil.rmtree(save_dir_subscript, ignore_errors=True)</span>\n        <span class=\"k\">if</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">isdir</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"kc\">False</span><span class=\"p\">:</span>\n            <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">makedirs</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_saver</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">sess</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_session</span><span class=\"p\">,</span> <span class=\"n\">save_path</span><span class=\"o\">=</span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">,</span> <span class=\"n\">subscript</span><span class=\"p\">),</span>\n                         <span class=\"n\">global_step</span><span class=\"o\">=</span><span class=\"n\">global_step</span><span class=\"p\">)</span></div>\n\n<div class=\"viewcode-block\" id=\"BaseModel.load\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.load\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">load</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">subscript</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            subscript: String, subscript will be appended to the code version as the model file name,</span>\n<span class=\"sd\">                and load the corresponding model using this filename</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">save_dir_subscript</span> <span class=\"o\">=</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_log_dir</span><span class=\"p\">,</span> <span class=\"n\">subscript</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">listdir</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">))</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;model Not Found&#39;</span><span class=\"p\">)</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">FileNotFoundError</span><span class=\"p\">(</span><span class=\"n\">subscript</span><span class=\"p\">,</span> <span class=\"s1\">&#39;model not found&#39;</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">meta_file</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">e</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">listdir</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">startswith</span><span class=\"p\">(</span><span class=\"n\">subscript</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">endswith</span><span class=\"p\">(</span><span class=\"s1\">&#39;.meta&#39;</span><span class=\"p\">)]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_global_step</span> <span class=\"o\">=</span> <span class=\"nb\">max</span><span class=\"p\">([</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"s1\">&#39;.&#39;</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"s1\">&#39;-&#39;</span><span class=\"p\">)[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">meta_file</span><span class=\"p\">])</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_saver</span><span class=\"o\">.</span><span class=\"n\">restore</span><span class=\"p\">(</span><span class=\"n\">sess</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_session</span><span class=\"p\">,</span>\n                                <span class=\"n\">save_path</span><span class=\"o\">=</span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">save_dir_subscript</span><span class=\"p\">,</span> <span class=\"n\">subscript</span> <span class=\"o\">+</span> <span class=\"s1\">&#39;-</span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_global_step</span><span class=\"p\">))</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_global_step</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span>\n            <span class=\"c1\"># parse the log-file</span>\n            <span class=\"n\">log_list</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_get_log</span><span class=\"p\">()</span>\n            <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">log_list</span><span class=\"p\">:</span>\n                <span class=\"k\">if</span> <span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;converged&#39;</span><span class=\"p\">:</span>\n                    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_converged</span> <span class=\"o\">=</span> <span class=\"kc\">True</span></div>\n\n<div class=\"viewcode-block\" id=\"BaseModel.close\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.close\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">close</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Close the session, release memory.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_session</span><span class=\"o\">.</span><span class=\"n\">close</span><span class=\"p\">()</span></div>\n\n<div class=\"viewcode-block\" id=\"BaseModel.load_event_scalar\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.load_event_scalar\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">load_event_scalar</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">scalar_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;val_loss&#39;</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            scalar_name: load the corresponding scalar name from tensorboard-file,</span>\n<span class=\"sd\">                e.g. load_event_scalar(&#39;val_loss)</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">event_files</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">e</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">listdir</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_log_dir</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">startswith</span><span class=\"p\">(</span><span class=\"s1\">&#39;events.out&#39;</span><span class=\"p\">)]</span>\n        <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"k\">for</span> <span class=\"n\">f</span> <span class=\"ow\">in</span> <span class=\"n\">event_files</span><span class=\"p\">:</span>\n            <span class=\"n\">ea</span> <span class=\"o\">=</span> <span class=\"n\">event_accumulator</span><span class=\"o\">.</span><span class=\"n\">EventAccumulator</span><span class=\"p\">(</span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_log_dir</span><span class=\"p\">,</span> <span class=\"n\">f</span><span class=\"p\">))</span>\n            <span class=\"n\">ea</span><span class=\"o\">.</span><span class=\"n\">Reload</span><span class=\"p\">()</span>\n            <span class=\"k\">if</span> <span class=\"n\">scalar_name</span> <span class=\"ow\">in</span> <span class=\"n\">ea</span><span class=\"o\">.</span><span class=\"n\">scalars</span><span class=\"o\">.</span><span class=\"n\">Keys</span><span class=\"p\">():</span>\n                <span class=\"n\">result</span> <span class=\"o\">+=</span> <span class=\"p\">[[</span><span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">wall_time</span><span class=\"p\">,</span> <span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">step</span><span class=\"p\">,</span> <span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">value</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">ea</span><span class=\"o\">.</span><span class=\"n\">scalars</span><span class=\"o\">.</span><span class=\"n\">Items</span><span class=\"p\">(</span><span class=\"n\">scalar_name</span><span class=\"p\">)]</span>\n        <span class=\"k\">return</span> <span class=\"n\">result</span></div></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model_unit/DCRNN_CELL.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model_unit.DCRNN_CELL &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model_unit.DCRNN_CELL</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">from</span> <span class=\"nn\">__future__</span> <span class=\"k\">import</span> <span class=\"n\">absolute_import</span>\n<span class=\"kn\">from</span> <span class=\"nn\">__future__</span> <span class=\"k\">import</span> <span class=\"n\">division</span>\n<span class=\"kn\">from</span> <span class=\"nn\">__future__</span> <span class=\"k\">import</span> <span class=\"n\">print_function</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.contrib.rnn</span> <span class=\"k\">import</span> <span class=\"n\">RNNCell</span>\n\n\n<div class=\"viewcode-block\" id=\"DCGRUCell\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">DCGRUCell</span><span class=\"p\">(</span><span class=\"n\">RNNCell</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Graph Convolution Gated Recurrent Unit cell.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n<div class=\"viewcode-block\" id=\"DCGRUCell.call\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell.call\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">call</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"k\">pass</span></div>\n\n<div class=\"viewcode-block\" id=\"DCGRUCell.compute_output_shape\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell.compute_output_shape\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">compute_output_shape</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">input_shape</span><span class=\"p\">):</span>\n        <span class=\"k\">pass</span></div>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">num_units</span><span class=\"p\">,</span> <span class=\"n\">input_dim</span><span class=\"p\">,</span> <span class=\"n\">num_graphs</span><span class=\"p\">,</span> <span class=\"n\">supports</span><span class=\"p\">,</span> <span class=\"n\">max_diffusion_step</span><span class=\"p\">,</span> <span class=\"n\">num_nodes</span><span class=\"p\">,</span> <span class=\"n\">num_proj</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                 <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">,</span> <span class=\"n\">reuse</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">use_gc_for_ru</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;</span>\n\n<span class=\"sd\">        :param num_units:</span>\n<span class=\"sd\">        :param adj_mx:</span>\n<span class=\"sd\">        :param max_diffusion_step:</span>\n<span class=\"sd\">        :param num_nodes:</span>\n<span class=\"sd\">        :param input_size:</span>\n<span class=\"sd\">        :param num_proj:</span>\n<span class=\"sd\">        :param activation:</span>\n<span class=\"sd\">        :param reuse:</span>\n<span class=\"sd\">        :param filter_type: &quot;laplacian&quot;, &quot;random_walk&quot;, &quot;dual_random_walk&quot;.</span>\n<span class=\"sd\">        :param use_gc_for_ru: whether to use Graph convolution to calculate the reset and update gates.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">DCGRUCell</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">_reuse</span><span class=\"o\">=</span><span class=\"n\">reuse</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_activation</span> <span class=\"o\">=</span> <span class=\"n\">activation</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">=</span> <span class=\"n\">num_nodes</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input_dim</span> <span class=\"o\">=</span> <span class=\"n\">input_dim</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_graphs</span> <span class=\"o\">=</span> <span class=\"n\">num_graphs</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_proj</span> <span class=\"o\">=</span> <span class=\"n\">num_proj</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_units</span> <span class=\"o\">=</span> <span class=\"n\">num_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_max_diffusion_step</span> <span class=\"o\">=</span> <span class=\"n\">max_diffusion_step</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_use_gc_for_ru</span> <span class=\"o\">=</span> <span class=\"n\">use_gc_for_ru</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_supports</span> <span class=\"o\">=</span> <span class=\"n\">supports</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_diff_matrix</span> <span class=\"o\">=</span> <span class=\"n\">supports</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_name</span> <span class=\"o\">=</span> <span class=\"n\">name</span>\n\n    <span class=\"nd\">@property</span>\n    <span class=\"k\">def</span> <span class=\"nf\">state_size</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_units</span>\n\n    <span class=\"nd\">@property</span>\n    <span class=\"k\">def</span> <span class=\"nf\">output_size</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">output_size</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_units</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_proj</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">output_size</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_proj</span>\n        <span class=\"k\">return</span> <span class=\"n\">output_size</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__call__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">scope</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Gated recurrent unit (GRU) with Graph Convolution.</span>\n<span class=\"sd\">        :param inputs: (B, num_nodes * input_dim)</span>\n\n<span class=\"sd\">        :return</span>\n<span class=\"sd\">        - Output: A `2-D` tensor with shape `[batch_size x self.output_size]`.</span>\n<span class=\"sd\">        - New state: Either a single `2-D` tensor, or a tuple of tensors matching</span>\n<span class=\"sd\">            the arity and shapes of `state`</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"n\">scope</span> <span class=\"ow\">or</span> <span class=\"s2\">&quot;dcgru_cell&quot;</span><span class=\"p\">):</span>\n            <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s2\">&quot;gates&quot;</span><span class=\"p\">):</span>  <span class=\"c1\"># Reset gate and update gate.</span>\n                <span class=\"n\">output_size</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_units</span>\n                <span class=\"c1\"># We start with bias of 1.0 to not reset and not update.</span>\n                <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_use_gc_for_ru</span><span class=\"p\">:</span>\n                    <span class=\"n\">fn</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gconv</span>\n                <span class=\"k\">else</span><span class=\"p\">:</span>\n                    <span class=\"n\">fn</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_fc</span>\n                <span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">sigmoid</span><span class=\"p\">(</span><span class=\"n\">fn</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"p\">,</span> <span class=\"n\">bias_start</span><span class=\"o\">=</span><span class=\"mf\">1.0</span><span class=\"p\">))</span>\n                <span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"p\">))</span>\n                <span class=\"n\">r</span><span class=\"p\">,</span> <span class=\"n\">u</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"o\">=</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">num_or_size_splits</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n                <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">r</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_units</span><span class=\"p\">))</span>\n                <span class=\"n\">u</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">u</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_units</span><span class=\"p\">))</span>\n            <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s2\">&quot;candidate&quot;</span><span class=\"p\">):</span>\n                <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gconv</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">r</span> <span class=\"o\">*</span> <span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_units</span><span class=\"p\">)</span>\n                <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_activation</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n                    <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_activation</span><span class=\"p\">(</span><span class=\"n\">c</span><span class=\"p\">)</span>\n            <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"n\">new_state</span> <span class=\"o\">=</span> <span class=\"n\">u</span> <span class=\"o\">*</span> <span class=\"n\">state</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"mi\">1</span> <span class=\"o\">-</span> <span class=\"n\">u</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"n\">c</span>\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_proj</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s2\">&quot;projection&quot;</span><span class=\"p\">):</span>\n                    <span class=\"n\">w</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s1\">&#39;w&#39;</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_units</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_proj</span><span class=\"p\">))</span>\n                    <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">new_state</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_units</span><span class=\"p\">))</span>\n                    <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">output</span><span class=\"p\">,</span> <span class=\"n\">w</span><span class=\"p\">),</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_size</span><span class=\"p\">))</span>\n        <span class=\"k\">return</span> <span class=\"n\">output</span><span class=\"p\">,</span> <span class=\"n\">new_state</span>\n\n    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">_concat</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">x_</span><span class=\"p\">):</span>\n        <span class=\"n\">x_</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">expand_dims</span><span class=\"p\">(</span><span class=\"n\">x_</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">x_</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_fc</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"p\">,</span> <span class=\"n\">bias_start</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">):</span>\n        <span class=\"n\">dtype</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">dtype</span>\n        <span class=\"n\">batch_size</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n        <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">batch_size</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n        <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">batch_size</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n        <span class=\"n\">inputs_and_state</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n        <span class=\"n\">input_size</span> <span class=\"o\">=</span> <span class=\"n\">inputs_and_state</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n        <span class=\"n\">weights</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span>\n            <span class=\"s1\">&#39;weights&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">input_size</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">dtype</span><span class=\"p\">,</span>\n            <span class=\"n\">initializer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">xavier_initializer</span><span class=\"p\">())</span>\n        <span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">sigmoid</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">inputs_and_state</span><span class=\"p\">,</span> <span class=\"n\">weights</span><span class=\"p\">))</span>\n        <span class=\"n\">biases</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s2\">&quot;biases&quot;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">output_size</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">dtype</span><span class=\"p\">,</span>\n                                 <span class=\"n\">initializer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">constant_initializer</span><span class=\"p\">(</span><span class=\"n\">bias_start</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">dtype</span><span class=\"p\">))</span>\n        <span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">bias_add</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">biases</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">value</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_gconv</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"p\">,</span> <span class=\"n\">bias_start</span><span class=\"o\">=</span><span class=\"mf\">0.0</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Graph convolution between input and the graph matrix.</span>\n\n<span class=\"sd\">        :param args: a 2D Tensor or a list of 2D, batch x n, Tensors.</span>\n<span class=\"sd\">        :param output_size:</span>\n<span class=\"sd\">        :param bias:</span>\n<span class=\"sd\">        :param bias_start:</span>\n<span class=\"sd\">        :param scope:</span>\n<span class=\"sd\">        :return:</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># Reshape input and state to (batch_size, num_nodes, input_dim/state_dim)</span>\n        <span class=\"n\">last_dim</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n        <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">last_dim</span> <span class=\"o\">/</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">)))</span>\n        <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_units</span><span class=\"p\">))</span>\n        <span class=\"n\">inputs_and_state</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n        <span class=\"n\">input_size</span> <span class=\"o\">=</span> <span class=\"n\">inputs_and_state</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n        <span class=\"n\">dtype</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">dtype</span>\n\n        <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">inputs_and_state</span>\n        <span class=\"n\">x0</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">perm</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>  <span class=\"c1\"># (num_nodes, total_arg_size, batch_size)</span>\n        <span class=\"n\">x0</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">x0</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n        <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">expand_dims</span><span class=\"p\">(</span><span class=\"n\">x0</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n\n        <span class=\"n\">scope</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable_scope</span><span class=\"p\">()</span>\n        <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"n\">scope</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"ow\">or</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">),</span> <span class=\"n\">reuse</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span>\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_max_diffusion_step</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"k\">pass</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"k\">for</span> <span class=\"n\">index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_diff_matrix</span><span class=\"p\">):</span>\n                    <span class=\"n\">x1</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_supports</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">],</span> <span class=\"n\">x0</span><span class=\"p\">)</span>\n                    <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_concat</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">x1</span><span class=\"p\">)</span>\n\n                    <span class=\"k\">for</span> <span class=\"n\">k</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_max_diffusion_step</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">):</span>\n                        <span class=\"n\">x2</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_supports</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">],</span> <span class=\"n\">x1</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"n\">x0</span>\n                        <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_concat</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">x2</span><span class=\"p\">)</span>\n                        <span class=\"n\">x1</span><span class=\"p\">,</span> <span class=\"n\">x0</span> <span class=\"o\">=</span> <span class=\"n\">x2</span><span class=\"p\">,</span> <span class=\"n\">x1</span>\n\n            <span class=\"n\">num_matrices</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_diff_matrix</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_max_diffusion_step</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>  <span class=\"c1\"># Adds for x itself.</span>\n            <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">num_matrices</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span><span class=\"p\">,</span> <span class=\"n\">input_size</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n            <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">perm</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>  <span class=\"c1\"># (batch_size, num_nodes, input_size, order)</span>\n            <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">input_size</span> <span class=\"o\">*</span> <span class=\"n\">num_matrices</span><span class=\"p\">])</span>\n\n            <span class=\"n\">weights</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span>\n                <span class=\"s1\">&#39;weights&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">input_size</span> <span class=\"o\">*</span> <span class=\"n\">num_matrices</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">dtype</span><span class=\"p\">,</span>\n                <span class=\"n\">initializer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">xavier_initializer</span><span class=\"p\">())</span>\n            <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">weights</span><span class=\"p\">)</span>  <span class=\"c1\"># (batch_size * self._num_nodes, output_size)</span>\n\n            <span class=\"n\">biases</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s2\">&quot;biases&quot;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">output_size</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">dtype</span><span class=\"p\">,</span>\n                                     <span class=\"n\">initializer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">constant_initializer</span><span class=\"p\">(</span><span class=\"n\">bias_start</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">dtype</span><span class=\"p\">))</span>\n            <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">bias_add</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">biases</span><span class=\"p\">)</span>\n        <span class=\"c1\"># Reshape res back to 2D: (batch_size, num_node, state_dim) -&gt; (batch_size, num_node * state_dim)</span>\n        <span class=\"k\">return</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_nodes</span> <span class=\"o\">*</span> <span class=\"n\">output_size</span><span class=\"p\">])</span></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model_unit/GraphModelLayers.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model_unit.GraphModelLayers &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model_unit.GraphModelLayers</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">math</span> <span class=\"k\">import</span> <span class=\"n\">radians</span><span class=\"p\">,</span> <span class=\"n\">cos</span><span class=\"p\">,</span> <span class=\"n\">sin</span><span class=\"p\">,</span> <span class=\"n\">asin</span><span class=\"p\">,</span> <span class=\"n\">sqrt</span>\n<span class=\"kn\">from</span> <span class=\"nn\">scipy.stats</span> <span class=\"k\">import</span> <span class=\"n\">pearsonr</span>\n\n\n<div class=\"viewcode-block\" id=\"GraphBuilder\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GraphBuilder\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">GraphBuilder</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n<div class=\"viewcode-block\" id=\"GraphBuilder.haversine\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GraphBuilder.haversine\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">haversine</span><span class=\"p\">(</span><span class=\"n\">lat1</span><span class=\"p\">,</span> <span class=\"n\">lon1</span><span class=\"p\">,</span> <span class=\"n\">lat2</span><span class=\"p\">,</span> <span class=\"n\">lon2</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Calculate the great circle distance between two points</span>\n<span class=\"sd\">        on the earth (specified in decimal degrees)</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">lon1</span><span class=\"p\">,</span> <span class=\"n\">lat1</span><span class=\"p\">,</span> <span class=\"n\">lon2</span><span class=\"p\">,</span> <span class=\"n\">lat2</span> <span class=\"o\">=</span> <span class=\"nb\">map</span><span class=\"p\">(</span><span class=\"n\">radians</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">lon1</span><span class=\"p\">,</span> <span class=\"n\">lat1</span><span class=\"p\">,</span> <span class=\"n\">lon2</span><span class=\"p\">,</span> <span class=\"n\">lat2</span><span class=\"p\">])</span>\n\n        <span class=\"c1\"># haversine</span>\n        <span class=\"n\">dlon</span> <span class=\"o\">=</span> <span class=\"n\">lon2</span> <span class=\"o\">-</span> <span class=\"n\">lon1</span>\n        <span class=\"n\">dlat</span> <span class=\"o\">=</span> <span class=\"n\">lat2</span> <span class=\"o\">-</span> <span class=\"n\">lat1</span>\n        <span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"n\">sin</span><span class=\"p\">(</span><span class=\"n\">dlat</span> <span class=\"o\">/</span> <span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"o\">**</span> <span class=\"mi\">2</span> <span class=\"o\">+</span> <span class=\"n\">cos</span><span class=\"p\">(</span><span class=\"n\">lat1</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"n\">cos</span><span class=\"p\">(</span><span class=\"n\">lat2</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"n\">sin</span><span class=\"p\">(</span><span class=\"n\">dlon</span> <span class=\"o\">/</span> <span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"o\">**</span> <span class=\"mi\">2</span>\n        <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">asin</span><span class=\"p\">(</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">))</span>\n        <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"mi\">6371</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">c</span> <span class=\"o\">*</span> <span class=\"n\">r</span> <span class=\"o\">*</span> <span class=\"mi\">1000</span></div>\n\n<div class=\"viewcode-block\" id=\"GraphBuilder.correlation_adjacent\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GraphBuilder.correlation_adjacent\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">correlation_adjacent</span><span class=\"p\">(</span><span class=\"n\">traffic_data</span><span class=\"p\">,</span> <span class=\"n\">threshold</span><span class=\"p\">):</span>\n        <span class=\"n\">adjacent_matrix</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"n\">traffic_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">traffic_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]])</span>\n        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">traffic_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]):</span>\n            <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">traffic_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]):</span>\n                <span class=\"n\">r</span><span class=\"p\">,</span> <span class=\"n\">p_value</span> <span class=\"o\">=</span> <span class=\"n\">pearsonr</span><span class=\"p\">(</span><span class=\"n\">traffic_data</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">],</span> <span class=\"n\">traffic_data</span><span class=\"p\">[:,</span> <span class=\"n\">j</span><span class=\"p\">])</span>\n                <span class=\"n\">adjacent_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">if</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">isnan</span><span class=\"p\">(</span><span class=\"n\">r</span><span class=\"p\">)</span> <span class=\"k\">else</span> <span class=\"n\">r</span>\n        <span class=\"n\">adjacent_matrix</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">adjacent_matrix</span> <span class=\"o\">&gt;=</span> <span class=\"n\">threshold</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">adjacent_matrix</span></div>\n\n<div class=\"viewcode-block\" id=\"GraphBuilder.distance_adjacent\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GraphBuilder.distance_adjacent\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">distance_adjacent</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">,</span> <span class=\"n\">threshold</span><span class=\"p\">):</span>\n        <span class=\"n\">adjacent_matrix</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">)])</span>\n        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">)):</span>\n            <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">)):</span>\n                <span class=\"n\">adjacent_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">GraphBuilder</span><span class=\"o\">.</span><span class=\"n\">haversine</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">],</span>\n                                                               <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n        <span class=\"n\">adjacent_matrix</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">adjacent_matrix</span> <span class=\"o\">&lt;=</span> <span class=\"n\">threshold</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">adjacent_matrix</span></div>\n\n<div class=\"viewcode-block\" id=\"GraphBuilder.interaction_adjacent\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GraphBuilder.interaction_adjacent\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">interaction_adjacent</span><span class=\"p\">(</span><span class=\"n\">interaction_matrix</span><span class=\"p\">,</span> <span class=\"n\">threshold</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"p\">(</span><span class=\"n\">interaction_matrix</span> <span class=\"o\">&gt;=</span> <span class=\"n\">threshold</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span></div>\n\n<div class=\"viewcode-block\" id=\"GraphBuilder.adjacent_to_laplacian\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GraphBuilder.adjacent_to_laplacian\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">adjacent_to_laplacian</span><span class=\"p\">(</span><span class=\"n\">adjacent_matrix</span><span class=\"p\">):</span>\n        <span class=\"n\">adjacent_matrix</span> <span class=\"o\">-=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">diag</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">diag</span><span class=\"p\">(</span><span class=\"n\">adjacent_matrix</span><span class=\"p\">))</span>\n        <span class=\"n\">diagonal_matrix</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">diag</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">adjacent_matrix</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"o\">**</span> <span class=\"o\">-</span><span class=\"mf\">0.5</span><span class=\"p\">)</span>\n        <span class=\"n\">diagonal_matrix</span><span class=\"p\">[</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">isinf</span><span class=\"p\">(</span><span class=\"n\">diagonal_matrix</span><span class=\"p\">)]</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n        <span class=\"n\">laplacian_matrix</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">eye</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">adjacent_matrix</span><span class=\"p\">))</span> <span class=\"o\">-</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">dot</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">dot</span><span class=\"p\">(</span><span class=\"n\">diagonal_matrix</span><span class=\"p\">,</span> <span class=\"n\">adjacent_matrix</span><span class=\"p\">),</span>\n                                                                 <span class=\"n\">diagonal_matrix</span><span class=\"p\">)</span>\n        <span class=\"n\">laplacian_matrix</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">laplacian_matrix</span> <span class=\"o\">/</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">max</span><span class=\"p\">(</span><span class=\"n\">laplacian_matrix</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">eye</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">adjacent_matrix</span><span class=\"p\">))</span>\n        <span class=\"k\">return</span> <span class=\"n\">laplacian_matrix</span></div></div>\n\n\n<span class=\"c1\"># Graph Attention Layer</span>\n<div class=\"viewcode-block\" id=\"GAL\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">GAL</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n\n<div class=\"viewcode-block\" id=\"GAL.attention_merge_weight\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL.attention_merge_weight\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">attention_merge_weight</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"p\">,</span> <span class=\"n\">num_head</span><span class=\"p\">,</span> <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">leaky_relu</span><span class=\"p\">):</span>\n\n        <span class=\"n\">inputs_shape</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">with_rank</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">)</span>\n\n        <span class=\"n\">num_node</span> <span class=\"o\">=</span> <span class=\"n\">inputs_shape</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n        <span class=\"n\">num_feature</span> <span class=\"o\">=</span> <span class=\"n\">inputs_shape</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n\n        <span class=\"n\">W</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">random_normal</span><span class=\"p\">([</span><span class=\"n\">num_feature</span><span class=\"p\">,</span> <span class=\"n\">units</span> <span class=\"o\">*</span> <span class=\"n\">num_head</span><span class=\"p\">]))</span>\n\n        <span class=\"c1\"># linear transform</span>\n        <span class=\"n\">l_t</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_feature</span><span class=\"p\">]),</span> <span class=\"n\">W</span><span class=\"p\">)</span>\n        <span class=\"n\">l_t</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">l_t</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_node</span><span class=\"p\">,</span> <span class=\"n\">num_head</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"p\">])</span>\n\n        <span class=\"c1\"># compute attention</span>\n        <span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">random_normal</span><span class=\"p\">([</span><span class=\"n\">units</span> <span class=\"o\">*</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">num_head</span><span class=\"p\">]))</span>\n\n        <span class=\"n\">e</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_node</span><span class=\"p\">):</span>\n            <span class=\"n\">multi_head_result</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            <span class=\"k\">for</span> <span class=\"n\">k</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_head</span><span class=\"p\">):</span>\n                <span class=\"n\">multi_head_result</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">l_t</span><span class=\"p\">[:,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"p\">:],</span> <span class=\"n\">l_t</span><span class=\"p\">[:,</span> <span class=\"n\">j</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"p\">:]],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"n\">a</span><span class=\"p\">[:,</span> <span class=\"n\">k</span><span class=\"p\">:</span><span class=\"n\">k</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">]))</span>\n            <span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">multi_head_result</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_head</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]))</span>\n\n        <span class=\"n\">e</span> <span class=\"o\">=</span> <span class=\"n\">activation</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_head</span><span class=\"p\">,</span> <span class=\"n\">num_node</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]))</span>\n\n        <span class=\"n\">alpha</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">softmax</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">keepdims</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">alpha</span></div>\n\n<div class=\"viewcode-block\" id=\"GAL.add_ga_layer_matrix\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL.add_ga_layer_matrix\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">add_ga_layer_matrix</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"p\">,</span> <span class=\"n\">num_head</span><span class=\"p\">,</span> <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">):</span>\n\n        <span class=\"n\">inputs_shape</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">with_rank</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">)</span>\n\n        <span class=\"n\">num_node</span> <span class=\"o\">=</span> <span class=\"n\">inputs_shape</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n        <span class=\"n\">num_feature</span> <span class=\"o\">=</span> <span class=\"n\">inputs_shape</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n\n        <span class=\"n\">W</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">random_normal</span><span class=\"p\">([</span><span class=\"n\">num_feature</span><span class=\"p\">,</span> <span class=\"n\">units</span> <span class=\"o\">*</span> <span class=\"n\">num_head</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">))</span>\n\n        <span class=\"c1\"># linear transform</span>\n        <span class=\"n\">l_t</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_feature</span><span class=\"p\">]),</span> <span class=\"n\">W</span><span class=\"p\">)</span>\n        <span class=\"n\">l_t</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">l_t</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_node</span><span class=\"p\">,</span> <span class=\"n\">num_head</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"p\">])</span>\n\n        <span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">random_normal</span><span class=\"p\">([</span><span class=\"n\">units</span> <span class=\"o\">*</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">num_head</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">))</span>\n\n        <span class=\"n\">e_multi_head</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">head_index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_head</span><span class=\"p\">):</span>\n\n            <span class=\"n\">l_t_i</span> <span class=\"o\">=</span> <span class=\"n\">l_t</span><span class=\"p\">[:,</span> <span class=\"p\">:,</span> <span class=\"n\">head_index</span><span class=\"p\">,</span> <span class=\"p\">:]</span>\n            <span class=\"n\">a_i</span> <span class=\"o\">=</span> <span class=\"n\">a</span><span class=\"p\">[:,</span> <span class=\"n\">head_index</span><span class=\"p\">:</span><span class=\"n\">head_index</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n\n            <span class=\"n\">l_t_i_0</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">gather</span><span class=\"p\">(</span><span class=\"n\">l_t_i</span><span class=\"p\">,</span> <span class=\"n\">indices</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">e</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_node</span><span class=\"p\">)]</span> <span class=\"o\">*</span> <span class=\"n\">num_node</span><span class=\"p\">),</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n            <span class=\"n\">l_t_i_1</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">gather</span><span class=\"p\">(</span><span class=\"n\">l_t_i</span><span class=\"p\">,</span> <span class=\"n\">indices</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([[</span><span class=\"n\">e</span><span class=\"p\">]</span><span class=\"o\">*</span><span class=\"n\">num_node</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_node</span><span class=\"p\">)])</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,]),</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"n\">tmp_e</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">((</span><span class=\"n\">l_t_i_0</span><span class=\"p\">,</span> <span class=\"n\">l_t_i_1</span><span class=\"p\">),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"o\">*</span><span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"n\">a_i</span><span class=\"p\">)</span>\n            <span class=\"n\">tmp_e</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">softmax</span><span class=\"p\">(</span><span class=\"n\">activation</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tmp_e</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_node</span><span class=\"p\">,</span> <span class=\"n\">num_node</span><span class=\"p\">])),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n            <span class=\"n\">e_multi_head</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tmp_e</span><span class=\"p\">)</span>\n\n        <span class=\"n\">alpha</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">(</span><span class=\"n\">e_multi_head</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Averaging</span>\n        <span class=\"n\">gc_output</span> <span class=\"o\">=</span> <span class=\"n\">activation</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">alpha</span><span class=\"p\">,</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">l_t</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">])),</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">alpha</span><span class=\"p\">,</span> <span class=\"n\">gc_output</span></div>\n\n<div class=\"viewcode-block\" id=\"GAL.add_residual_ga_layer\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL.add_residual_ga_layer\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">add_residual_ga_layer</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"p\">,</span> <span class=\"n\">num_head</span><span class=\"p\">,</span> <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">):</span>\n\n        <span class=\"n\">_</span><span class=\"p\">,</span> <span class=\"n\">gc_output</span> <span class=\"o\">=</span> <span class=\"n\">GAL</span><span class=\"o\">.</span><span class=\"n\">add_ga_layer_matrix</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"p\">,</span> <span class=\"n\">num_head</span><span class=\"p\">,</span> <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">activation</span><span class=\"p\">)</span>\n\n        <span class=\"n\">gc_output_residual</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">concat</span><span class=\"p\">([</span><span class=\"n\">gc_output</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">gc_output_residual</span></div></div>\n\n\n<span class=\"c1\"># Graph Convolution Layer</span>\n<div class=\"viewcode-block\" id=\"GCL\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GCL\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">GCL</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n\n<div class=\"viewcode-block\" id=\"GCL.add_gc_layer\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GCL.add_gc_layer\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">add_gc_layer</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span>\n                     <span class=\"n\">gcn_k</span><span class=\"p\">,</span>\n                     <span class=\"n\">laplacian_matrix</span><span class=\"p\">,</span>\n                     <span class=\"n\">output_size</span><span class=\"p\">,</span>\n                     <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span>\n                     <span class=\"n\">use_bias</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                     <span class=\"n\">trainable</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                     <span class=\"n\">initializer</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                     <span class=\"n\">regularizer</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                     <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">):</span>\n\n        <span class=\"c1\"># [batch_size, num_node, num_feature]</span>\n        <span class=\"n\">input_shape</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">with_rank</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">)</span>\n\n        <span class=\"n\">num_node</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">)[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">]</span>\n        <span class=\"n\">num_feature</span> <span class=\"o\">=</span> <span class=\"n\">input_shape</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n\n        <span class=\"c1\"># GC on inputs</span>\n        <span class=\"c1\"># reshape from [batch, num_node, num_feature] into [num_node, batch*num_feature]</span>\n        <span class=\"n\">gc_input</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">perm</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"n\">num_node</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n\n        <span class=\"c1\"># Chebyshev polynomials</span>\n        <span class=\"c1\"># Reference: https://github.com/mdeff/cnn_graph</span>\n        <span class=\"n\">gc_outputs</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">()</span>\n        <span class=\"c1\"># Xt_0 = T_0 X = I X = X.</span>\n        <span class=\"n\">gc_outputs</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">gc_input</span><span class=\"p\">)</span>\n        <span class=\"c1\"># Xt_1 = T_1 X = L X.</span>\n        <span class=\"k\">if</span> <span class=\"n\">gcn_k</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n            <span class=\"n\">gc_outputs</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">laplacian_matrix</span><span class=\"p\">,</span> <span class=\"n\">gc_input</span><span class=\"p\">))</span>\n        <span class=\"c1\"># Xt_k = 2 L Xt_k-1 - Xt_k-2.</span>\n        <span class=\"k\">for</span> <span class=\"n\">k</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">gcn_k</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">):</span>\n            <span class=\"n\">gc_outputs</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">laplacian_matrix</span><span class=\"p\">,</span> <span class=\"n\">gc_outputs</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"o\">-</span> <span class=\"n\">gc_outputs</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n\n        <span class=\"c1\"># [gcn_k+1, number_nodes, batch*num_feature]</span>\n        <span class=\"n\">gc_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">gc_outputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">gcn_k</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_node</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_feature</span><span class=\"p\">])</span>\n        <span class=\"c1\"># [batch, number_nodes, num_feature, gcn_k+1]</span>\n        <span class=\"n\">gc_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">gc_outputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n        <span class=\"c1\"># [batch*number_nodes, num_feature*gcn_k+1]</span>\n        <span class=\"n\">gc_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">gc_outputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_feature</span><span class=\"o\">*</span><span class=\"p\">(</span><span class=\"n\">gcn_k</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">)])</span>\n\n        <span class=\"n\">output_weight</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s2\">&quot;weights&quot;</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">num_feature</span><span class=\"o\">*</span><span class=\"p\">(</span><span class=\"n\">gcn_k</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"n\">output_size</span><span class=\"p\">],</span>\n                                        <span class=\"n\">trainable</span><span class=\"o\">=</span><span class=\"n\">trainable</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">dtype</span><span class=\"p\">,</span>\n                                        <span class=\"n\">initializer</span><span class=\"o\">=</span><span class=\"n\">initializer</span><span class=\"p\">,</span> <span class=\"n\">regularizer</span><span class=\"o\">=</span><span class=\"n\">regularizer</span><span class=\"p\">)</span>\n        <span class=\"n\">gc_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">gc_outputs</span><span class=\"p\">,</span> <span class=\"n\">output_weight</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">use_bias</span><span class=\"p\">:</span>\n            <span class=\"n\">biases</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">get_variable</span><span class=\"p\">(</span><span class=\"s2\">&quot;biases&quot;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">output_size</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">dtype</span><span class=\"p\">,</span>\n                                     <span class=\"n\">initializer</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">constant_initializer</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">dtype</span><span class=\"p\">))</span>\n            <span class=\"n\">gc_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">bias_add</span><span class=\"p\">(</span><span class=\"n\">gc_outputs</span><span class=\"p\">,</span> <span class=\"n\">biases</span><span class=\"p\">)</span>\n\n        <span class=\"n\">gc_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">gc_outputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_node</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"p\">])</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">activation</span><span class=\"p\">(</span><span class=\"n\">gc_outputs</span><span class=\"p\">)</span></div>\n\n<div class=\"viewcode-block\" id=\"GCL.add_multi_gc_layers\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GCL.add_multi_gc_layers\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">add_multi_gc_layers</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">gcn_k</span><span class=\"p\">,</span> <span class=\"n\">gcn_l</span><span class=\"p\">,</span> <span class=\"n\">output_size</span><span class=\"p\">,</span> <span class=\"n\">laplacian_matrix</span><span class=\"p\">,</span> <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">tanh</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;multi_gcl&#39;</span><span class=\"p\">,</span> <span class=\"n\">reuse</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span>\n            <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">gcn_l</span><span class=\"p\">):</span>\n                <span class=\"k\">with</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">variable_scope</span><span class=\"p\">(</span><span class=\"s1\">&#39;gcl_</span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">reuse</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span>\n                    <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">GCL</span><span class=\"o\">.</span><span class=\"n\">add_gc_layer</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">inputs</span><span class=\"p\">,</span>\n                                              <span class=\"n\">gcn_k</span><span class=\"o\">=</span><span class=\"n\">gcn_k</span><span class=\"p\">,</span>\n                                              <span class=\"n\">laplacian_matrix</span><span class=\"o\">=</span><span class=\"n\">laplacian_matrix</span><span class=\"p\">,</span>\n                                              <span class=\"n\">output_size</span><span class=\"o\">=</span><span class=\"n\">output_size</span><span class=\"p\">,</span>\n                                              <span class=\"n\">activation</span><span class=\"o\">=</span><span class=\"n\">activation</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">inputs</span></div></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/model_unit/ST_RNN.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.model_unit.ST_RNN &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.model_unit.ST_RNN</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.framework</span> <span class=\"k\">import</span> <span class=\"n\">dtypes</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.keras</span> <span class=\"k\">import</span> <span class=\"n\">backend</span> <span class=\"k\">as</span> <span class=\"n\">K</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.keras.utils</span> <span class=\"k\">import</span> <span class=\"n\">tf_utils</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.ops</span> <span class=\"k\">import</span> <span class=\"n\">array_ops</span><span class=\"p\">,</span> <span class=\"n\">linalg_ops</span><span class=\"p\">,</span> <span class=\"n\">math_ops</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_generate_dropout_mask</span><span class=\"p\">(</span><span class=\"n\">ones</span><span class=\"p\">,</span> <span class=\"n\">rate</span><span class=\"p\">,</span> <span class=\"n\">training</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">count</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">dropped_inputs</span><span class=\"p\">():</span>\n        <span class=\"k\">return</span> <span class=\"n\">K</span><span class=\"o\">.</span><span class=\"n\">dropout</span><span class=\"p\">(</span><span class=\"n\">ones</span><span class=\"p\">,</span> <span class=\"n\">rate</span><span class=\"p\">)</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">count</span> <span class=\"o\">&gt;</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"p\">[</span>\n            <span class=\"n\">K</span><span class=\"o\">.</span><span class=\"n\">in_train_phase</span><span class=\"p\">(</span><span class=\"n\">dropped_inputs</span><span class=\"p\">,</span> <span class=\"n\">ones</span><span class=\"p\">,</span> <span class=\"n\">training</span><span class=\"o\">=</span><span class=\"n\">training</span><span class=\"p\">)</span>\n            <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">count</span><span class=\"p\">)</span>\n        <span class=\"p\">]</span>\n    <span class=\"k\">return</span> <span class=\"n\">K</span><span class=\"o\">.</span><span class=\"n\">in_train_phase</span><span class=\"p\">(</span><span class=\"n\">dropped_inputs</span><span class=\"p\">,</span> <span class=\"n\">ones</span><span class=\"p\">,</span> <span class=\"n\">training</span><span class=\"o\">=</span><span class=\"n\">training</span><span class=\"p\">)</span>\n\n\n<div class=\"viewcode-block\" id=\"GCLSTMCell\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.ST_RNN.GCLSTMCell\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">GCLSTMCell</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">keras</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">LSTMCell</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">units</span><span class=\"p\">,</span> <span class=\"n\">num_nodes</span><span class=\"p\">,</span> <span class=\"n\">laplacian_matrix</span><span class=\"p\">,</span> <span class=\"n\">gcn_k</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">gcn_l</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">units</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_units</span> <span class=\"o\">=</span> <span class=\"n\">units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span> <span class=\"o\">=</span> <span class=\"n\">num_nodes</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span> <span class=\"o\">=</span> <span class=\"n\">gcn_k</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_l</span> <span class=\"o\">=</span> <span class=\"n\">gcn_l</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_laplacian_matrix</span> <span class=\"o\">=</span> <span class=\"n\">laplacian_matrix</span>\n\n    <span class=\"nd\">@tf_utils</span><span class=\"o\">.</span><span class=\"n\">shape_type_conversion</span>\n    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">input_shape</span><span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">GCLSTMCell</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">(</span><span class=\"n\">input_shape</span><span class=\"p\">)</span>\n        <span class=\"n\">input_dim</span> <span class=\"o\">=</span> <span class=\"n\">input_shape</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kernel</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_weight</span><span class=\"p\">(</span>\n            <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"n\">input_dim</span> <span class=\"o\">*</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">units</span> <span class=\"o\">*</span> <span class=\"mi\">4</span><span class=\"p\">),</span>\n            <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;kernel&#39;</span><span class=\"p\">,</span>\n            <span class=\"n\">initializer</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kernel_initializer</span><span class=\"p\">,</span>\n            <span class=\"n\">regularizer</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kernel_regularizer</span><span class=\"p\">,</span>\n            <span class=\"n\">constraint</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kernel_constraint</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">recurrent_kernel</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_weight</span><span class=\"p\">(</span>\n            <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">units</span> <span class=\"o\">*</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">units</span> <span class=\"o\">*</span> <span class=\"mi\">4</span><span class=\"p\">),</span>\n            <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;recurrent_kernel&#39;</span><span class=\"p\">,</span>\n            <span class=\"n\">initializer</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">recurrent_initializer</span><span class=\"p\">,</span>\n            <span class=\"n\">regularizer</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">recurrent_regularizer</span><span class=\"p\">,</span>\n            <span class=\"n\">constraint</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">recurrent_constraint</span><span class=\"p\">)</span>\n\n<div class=\"viewcode-block\" id=\"GCLSTMCell.kth_cheby_ploy\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.ST_RNN.GCLSTMCell.kth_cheby_ploy\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">kth_cheby_ploy</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">tk1</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">tk2</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"n\">k</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">linalg_ops</span><span class=\"o\">.</span><span class=\"n\">eye</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">dtypes</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n        <span class=\"k\">elif</span> <span class=\"n\">k</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_laplacian_matrix</span>\n        <span class=\"k\">elif</span> <span class=\"n\">k</span> <span class=\"o\">&gt;</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">math_ops</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_laplacian_matrix</span><span class=\"p\">,</span> <span class=\"n\">tk1</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"n\">tk2</span></div>\n\n<div class=\"viewcode-block\" id=\"GCLSTMCell.call\"><a class=\"viewcode-back\" href=\"../../../UCTB.model_unit.html#UCTB.model_unit.ST_RNN.GCLSTMCell.call\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">call</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">states</span><span class=\"p\">,</span> <span class=\"n\">training</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n\n        <span class=\"k\">if</span> <span class=\"mi\">0</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dropout</span> <span class=\"o\">&lt;</span> <span class=\"mi\">1</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dropout_mask</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dropout_mask</span> <span class=\"o\">=</span> <span class=\"n\">_generate_dropout_mask</span><span class=\"p\">(</span>\n                <span class=\"n\">array_ops</span><span class=\"o\">.</span><span class=\"n\">ones_like</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">),</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dropout</span><span class=\"p\">,</span>\n                <span class=\"n\">training</span><span class=\"o\">=</span><span class=\"n\">training</span><span class=\"p\">,</span>\n                <span class=\"n\">count</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"mi\">0</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">recurrent_dropout</span> <span class=\"o\">&lt;</span> <span class=\"mi\">1</span> <span class=\"ow\">and</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_recurrent_dropout_mask</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">):</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_recurrent_dropout_mask</span> <span class=\"o\">=</span> <span class=\"n\">_generate_dropout_mask</span><span class=\"p\">(</span>\n                <span class=\"n\">array_ops</span><span class=\"o\">.</span><span class=\"n\">ones_like</span><span class=\"p\">(</span><span class=\"n\">states</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]),</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">recurrent_dropout</span><span class=\"p\">,</span>\n                <span class=\"n\">training</span><span class=\"o\">=</span><span class=\"n\">training</span><span class=\"p\">,</span>\n                <span class=\"n\">count</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">)</span>\n\n        <span class=\"n\">input_dim</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">get_shape</span><span class=\"p\">()[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">value</span>\n\n        <span class=\"c1\"># dropout matrices for input units</span>\n        <span class=\"n\">dp_mask</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dropout_mask</span>\n        <span class=\"c1\"># dropout matrices for recurrent units</span>\n        <span class=\"n\">rec_dp_mask</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_recurrent_dropout_mask</span>\n\n        <span class=\"n\">h_tm1</span> <span class=\"o\">=</span> <span class=\"n\">states</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>  <span class=\"c1\"># previous memory state</span>\n        <span class=\"n\">c_tm1</span> <span class=\"o\">=</span> <span class=\"n\">states</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span>  <span class=\"c1\"># previous carry state</span>\n\n        <span class=\"k\">if</span> <span class=\"mf\">0.</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dropout</span> <span class=\"o\">&lt;</span> <span class=\"mf\">1.</span><span class=\"p\">:</span>\n            <span class=\"n\">inputs</span> <span class=\"o\">*=</span> <span class=\"n\">dp_mask</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n        <span class=\"k\">if</span> <span class=\"mf\">0.</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">recurrent_dropout</span> <span class=\"o\">&lt;</span> <span class=\"mf\">1.</span><span class=\"p\">:</span>\n            <span class=\"n\">h_tm1</span> <span class=\"o\">*=</span> <span class=\"n\">rec_dp_mask</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n        <span class=\"c1\"># inputs has shape: [batch * num_nodes, input_dim]</span>\n        <span class=\"c1\"># h_tm1 has shape: [batch * num_nodes, units]</span>\n        <span class=\"n\">inputs_before_gcn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"n\">input_dim</span><span class=\"p\">]),</span>\n                                                    <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n        <span class=\"n\">h_tm1_before_gcn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">h_tm1</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_units</span><span class=\"p\">]),</span>\n                                                   <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n\n        <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"n\">inputs_after_gcn</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">()</span>\n        <span class=\"n\">h_tm1_after_gcn</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">()</span>\n        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">):</span>\n            <span class=\"n\">t</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kth_cheby_ploy</span><span class=\"p\">(</span><span class=\"n\">k</span><span class=\"o\">=</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">tk1</span><span class=\"o\">=</span><span class=\"kc\">None</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">&lt;</span> <span class=\"mi\">1</span> <span class=\"k\">else</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"n\">i</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">tk2</span><span class=\"o\">=</span><span class=\"kc\">None</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">&lt;</span> <span class=\"mi\">2</span> <span class=\"k\">else</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"n\">i</span> <span class=\"o\">-</span> <span class=\"mi\">2</span><span class=\"p\">]))</span>\n            <span class=\"n\">inputs_after_gcn</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">t</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">inputs_before_gcn</span><span class=\"p\">))</span>\n            <span class=\"n\">h_tm1_after_gcn</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">matmul</span><span class=\"p\">(</span><span class=\"n\">t</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">h_tm1_before_gcn</span><span class=\"p\">))</span>\n\n        <span class=\"n\">inputs_after_gcn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">inputs_after_gcn</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">input_dim</span><span class=\"p\">])</span>\n        <span class=\"n\">h_tm1_after_gcn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">h_tm1_after_gcn</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_num_node</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_units</span><span class=\"p\">])</span>\n\n        <span class=\"n\">inputs_after_gcn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">inputs_after_gcn</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"n\">input_dim</span><span class=\"p\">])</span>\n        <span class=\"n\">h_tm1_after_gcn</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">h_tm1_after_gcn</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_gcn_k</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">units</span><span class=\"p\">])</span>\n\n        <span class=\"n\">z</span> <span class=\"o\">=</span> <span class=\"n\">K</span><span class=\"o\">.</span><span class=\"n\">dot</span><span class=\"p\">(</span><span class=\"n\">inputs_after_gcn</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kernel</span><span class=\"p\">)</span>\n        <span class=\"n\">z</span> <span class=\"o\">+=</span> <span class=\"n\">K</span><span class=\"o\">.</span><span class=\"n\">dot</span><span class=\"p\">(</span><span class=\"n\">h_tm1_after_gcn</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">recurrent_kernel</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">use_bias</span><span class=\"p\">:</span>\n            <span class=\"n\">z</span> <span class=\"o\">=</span> <span class=\"n\">K</span><span class=\"o\">.</span><span class=\"n\">bias_add</span><span class=\"p\">(</span><span class=\"n\">z</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">bias</span><span class=\"p\">)</span>\n\n        <span class=\"n\">z0</span> <span class=\"o\">=</span> <span class=\"n\">z</span><span class=\"p\">[:,</span> <span class=\"p\">:</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">units</span><span class=\"p\">]</span>\n        <span class=\"n\">z1</span> <span class=\"o\">=</span> <span class=\"n\">z</span><span class=\"p\">[:,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">units</span><span class=\"p\">:</span><span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">units</span><span class=\"p\">]</span>\n        <span class=\"n\">z2</span> <span class=\"o\">=</span> <span class=\"n\">z</span><span class=\"p\">[:,</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">units</span><span class=\"p\">:</span><span class=\"mi\">3</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">units</span><span class=\"p\">]</span>\n        <span class=\"n\">z3</span> <span class=\"o\">=</span> <span class=\"n\">z</span><span class=\"p\">[:,</span> <span class=\"mi\">3</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">units</span><span class=\"p\">:]</span>\n\n        <span class=\"n\">z</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">z0</span><span class=\"p\">,</span> <span class=\"n\">z1</span><span class=\"p\">,</span> <span class=\"n\">z2</span><span class=\"p\">,</span> <span class=\"n\">z3</span><span class=\"p\">)</span>\n        <span class=\"n\">c</span><span class=\"p\">,</span> <span class=\"n\">o</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_compute_carry_and_output_fused</span><span class=\"p\">(</span><span class=\"n\">z</span><span class=\"p\">,</span> <span class=\"n\">c_tm1</span><span class=\"p\">)</span>\n\n        <span class=\"n\">h</span> <span class=\"o\">=</span> <span class=\"n\">o</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">activation</span><span class=\"p\">(</span><span class=\"n\">c</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">h</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">h</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">]</span></div></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/preprocess/preprocessor.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.preprocess.preprocessor &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.preprocess.preprocessor</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n\n<div class=\"viewcode-block\" id=\"Normalizer\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.preprocessor.Normalizer\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">Normalizer</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_min</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">min</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_max</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">max</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n<div class=\"viewcode-block\" id=\"Normalizer.min_max_normal\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.preprocessor.Normalizer.min_max_normal\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">min_max_normal</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"p\">(</span><span class=\"n\">X</span> <span class=\"o\">-</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_min</span><span class=\"p\">)</span> <span class=\"o\">/</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_max</span> <span class=\"o\">-</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_min</span><span class=\"p\">)</span></div>\n\n<div class=\"viewcode-block\" id=\"Normalizer.min_max_denormal\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.preprocessor.Normalizer.min_max_denormal\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">min_max_denormal</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">X</span> <span class=\"o\">*</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_max</span> <span class=\"o\">-</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_min</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_min</span></div></div>\n\n    <span class=\"c1\"># def white_normal(self):</span>\n    <span class=\"c1\">#     pass</span>\n\n\n<div class=\"viewcode-block\" id=\"MoveSample\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.preprocessor.MoveSample\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">MoveSample</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">feature_step</span><span class=\"p\">,</span> <span class=\"n\">feature_stride</span><span class=\"p\">,</span> <span class=\"n\">feature_length</span><span class=\"p\">,</span> <span class=\"n\">target_length</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_step</span> <span class=\"o\">=</span> <span class=\"n\">feature_step</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_stride</span> <span class=\"o\">=</span> <span class=\"n\">feature_stride</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_length</span> <span class=\"o\">=</span> <span class=\"n\">feature_length</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">target_length</span> <span class=\"o\">=</span> <span class=\"n\">target_length</span>\n\n<div class=\"viewcode-block\" id=\"MoveSample.general_move_sample\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.preprocessor.MoveSample.general_move_sample\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">general_move_sample</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">):</span>\n        <span class=\"n\">feature</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"n\">target</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_length</span> <span class=\"o\">-</span>\n                       <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_step</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_stride</span> <span class=\"o\">-</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">target_length</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">):</span>\n            <span class=\"n\">feature</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">([</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"n\">step</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_stride</span><span class=\"p\">:</span> <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"n\">step</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_stride</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_length</span><span class=\"p\">]</span>\n                            <span class=\"k\">for</span> <span class=\"n\">step</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_step</span><span class=\"p\">)])</span>\n            <span class=\"n\">target</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_step</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_stride</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_length</span><span class=\"p\">:</span>\\\n                               <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_step</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_stride</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">feature_length</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">target_length</span><span class=\"p\">])</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">feature</span><span class=\"p\">),</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">target</span><span class=\"p\">)</span></div></div>\n\n\n<div class=\"viewcode-block\" id=\"ST_MoveSample\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.preprocessor.ST_MoveSample\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">ST_MoveSample</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">closeness_len</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"p\">,</span> <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">daily_slots</span><span class=\"o\">=</span><span class=\"mi\">24</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_c_t</span> <span class=\"o\">=</span> <span class=\"n\">closeness_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_p_t</span> <span class=\"o\">=</span> <span class=\"n\">period_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_t_t</span> <span class=\"o\">=</span> <span class=\"n\">trend_len</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_target_length</span> <span class=\"o\">=</span> <span class=\"n\">target_length</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_daily_slots</span> <span class=\"o\">=</span> <span class=\"n\">daily_slots</span>\n\n        <span class=\"c1\"># 1 init Move_Sample object</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">move_sample_closeness</span> <span class=\"o\">=</span> <span class=\"n\">MoveSample</span><span class=\"p\">(</span><span class=\"n\">feature_step</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_c_t</span><span class=\"p\">,</span> <span class=\"n\">feature_stride</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                                                <span class=\"n\">feature_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_target_length</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">move_sample_period</span> <span class=\"o\">=</span> <span class=\"n\">MoveSample</span><span class=\"p\">(</span><span class=\"n\">feature_step</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_p_t</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">feature_stride</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_daily_slots</span><span class=\"p\">),</span>\n                                             <span class=\"n\">feature_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">move_sample_trend</span> <span class=\"o\">=</span> <span class=\"n\">MoveSample</span><span class=\"p\">(</span><span class=\"n\">feature_step</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_t_t</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">feature_stride</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_daily_slots</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"mi\">7</span><span class=\"p\">,</span>\n                                            <span class=\"n\">feature_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n\n<div class=\"viewcode-block\" id=\"ST_MoveSample.move_sample\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.preprocessor.ST_MoveSample.move_sample\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">move_sample</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">):</span>\n\n        <span class=\"c1\"># 2 general move sample</span>\n        <span class=\"n\">closeness</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">move_sample_closeness</span><span class=\"o\">.</span><span class=\"n\">general_move_sample</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n        <span class=\"n\">period</span><span class=\"p\">,</span> <span class=\"n\">_</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">move_sample_period</span><span class=\"o\">.</span><span class=\"n\">general_move_sample</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n        <span class=\"n\">trend</span><span class=\"p\">,</span> <span class=\"n\">_</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">move_sample_trend</span><span class=\"o\">.</span><span class=\"n\">general_move_sample</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># 3 remove the front part</span>\n        <span class=\"n\">min_length</span> <span class=\"o\">=</span> <span class=\"nb\">min</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">closeness</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">period</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">trend</span><span class=\"p\">))</span>\n        <span class=\"n\">closeness</span> <span class=\"o\">=</span> <span class=\"n\">closeness</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"n\">min_length</span><span class=\"p\">:]</span>\n        <span class=\"n\">y</span> <span class=\"o\">=</span> <span class=\"n\">y</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"n\">min_length</span><span class=\"p\">:]</span>\n        <span class=\"n\">period</span> <span class=\"o\">=</span> <span class=\"n\">period</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"n\">min_length</span><span class=\"p\">:]</span>\n        <span class=\"n\">trend</span> <span class=\"o\">=</span> <span class=\"n\">trend</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"n\">min_length</span><span class=\"p\">:]</span>\n\n        <span class=\"c1\"># 4 remove tail of period and trend</span>\n        <span class=\"n\">period</span> <span class=\"o\">=</span> <span class=\"n\">period</span><span class=\"p\">[:,</span> <span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n        <span class=\"n\">trend</span> <span class=\"o\">=</span> <span class=\"n\">trend</span><span class=\"p\">[:,</span> <span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_c_t</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_c_t</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">closeness</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">closeness</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)))</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">])</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">closeness</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([])</span>\n\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_p_t</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_p_t</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">period</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">period</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">period</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)))</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">])</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">period</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([])</span>\n\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_t_t</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_t_t</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"n\">trend</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">trend</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">trend</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)))</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">])</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">trend</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([])</span>\n\n        <span class=\"n\">y</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">(</span><span class=\"n\">y</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)))</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">closeness</span><span class=\"p\">,</span> <span class=\"n\">period</span><span class=\"p\">,</span> <span class=\"n\">trend</span><span class=\"p\">,</span> <span class=\"n\">y</span></div></div>\n\n\n<div class=\"viewcode-block\" id=\"SplitData\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.preprocessor.SplitData\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">SplitData</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n\n<div class=\"viewcode-block\" id=\"SplitData.split_data\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.preprocessor.SplitData.split_data\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">split_data</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">,</span> <span class=\"n\">ratio_list</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">)</span> <span class=\"o\">!=</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n            <span class=\"n\">ratio_list</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">)</span>\n            <span class=\"n\">ratio_list</span> <span class=\"o\">=</span> <span class=\"n\">ratio_list</span> <span class=\"o\">/</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"p\">[</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"nb\">sum</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">:</span><span class=\"n\">e</span><span class=\"p\">])</span><span class=\"o\">*</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)):</span>\n                     <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"nb\">sum</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">:</span><span class=\"n\">e</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">])</span><span class=\"o\">*</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">))]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">))]</span></div>\n\n<div class=\"viewcode-block\" id=\"SplitData.split_feed_dict\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.preprocessor.SplitData.split_feed_dict\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">split_feed_dict</span><span class=\"p\">(</span><span class=\"n\">feed_dict</span><span class=\"p\">,</span> <span class=\"n\">sequence_length</span><span class=\"p\">,</span> <span class=\"n\">ratio_list</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">)</span> <span class=\"o\">!=</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n            <span class=\"n\">ratio_list</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">)</span>\n            <span class=\"n\">ratio_list</span> <span class=\"o\">=</span> <span class=\"n\">ratio_list</span> <span class=\"o\">/</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">)</span>\n\n        <span class=\"k\">return</span> <span class=\"p\">[{</span><span class=\"n\">key</span><span class=\"p\">:</span> <span class=\"n\">value</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"nb\">sum</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">:</span><span class=\"n\">e</span><span class=\"p\">])</span><span class=\"o\">*</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)):</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"nb\">sum</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">:</span><span class=\"n\">e</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">])</span><span class=\"o\">*</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">))]</span>\n                 <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"n\">sequence_length</span> <span class=\"k\">else</span> <span class=\"n\">value</span> <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span> <span class=\"ow\">in</span> <span class=\"n\">feed_dict</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">()}</span>\n                <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">ratio_list</span><span class=\"p\">))]</span></div></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/preprocess/time_utils.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.preprocess.time_utils &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.preprocess.time_utils</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">from</span> <span class=\"nn\">dateutil.parser</span> <span class=\"k\">import</span> <span class=\"n\">parse</span>\n<span class=\"kn\">from</span> <span class=\"nn\">chinese_calendar</span> <span class=\"k\">import</span> <span class=\"n\">is_workday</span>\n\n<span class=\"n\">america_public_holiday</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&#39;01-01&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;01-02&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;01-16&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;02-12&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;02-13&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;02-20&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;05-29&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;07-04&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;09-04&#39;</span><span class=\"p\">,</span>\n                          <span class=\"s1\">&#39;10-09&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;11-10&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;11-11&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;11-23&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;12-25&#39;</span><span class=\"p\">]</span>\n\n\n<div class=\"viewcode-block\" id=\"is_work_day_america\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.time_utils.is_work_day_america\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">is_work_day_america</span><span class=\"p\">(</span><span class=\"n\">date</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">date</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">str</span><span class=\"p\">:</span>\n        <span class=\"n\">date</span> <span class=\"o\">=</span> <span class=\"n\">parse</span><span class=\"p\">(</span><span class=\"n\">date</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">date</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"s1\">&#39;%m-</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span><span class=\"p\">)</span> <span class=\"ow\">in</span> <span class=\"n\">america_public_holiday</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"kc\">False</span>\n    <span class=\"n\">week</span> <span class=\"o\">=</span> <span class=\"n\">date</span><span class=\"o\">.</span><span class=\"n\">weekday</span><span class=\"p\">()</span>\n    <span class=\"k\">if</span> <span class=\"n\">week</span> <span class=\"o\">&lt;</span> <span class=\"mi\">5</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"kc\">True</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"kc\">False</span></div>\n\n\n<div class=\"viewcode-block\" id=\"is_work_day_china\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.time_utils.is_work_day_china\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">is_work_day_china</span><span class=\"p\">(</span><span class=\"n\">date</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">date</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">str</span><span class=\"p\">:</span>\n        <span class=\"n\">date</span> <span class=\"o\">=</span> <span class=\"n\">parse</span><span class=\"p\">(</span><span class=\"n\">date</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">is_workday</span><span class=\"p\">(</span><span class=\"n\">date</span><span class=\"p\">)</span></div>\n\n\n<div class=\"viewcode-block\" id=\"is_valid_date\"><a class=\"viewcode-back\" href=\"../../../UCTB.preprocess.html#UCTB.preprocess.time_utils.is_valid_date\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">is_valid_date</span><span class=\"p\">(</span><span class=\"n\">date_str</span><span class=\"p\">):</span>\n\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"n\">date</span> <span class=\"o\">=</span> <span class=\"n\">parse</span><span class=\"p\">(</span><span class=\"n\">date_str</span><span class=\"p\">)</span>\n    <span class=\"k\">except</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"kc\">False</span>\n\n    <span class=\"n\">year</span> <span class=\"o\">=</span> <span class=\"n\">date</span><span class=\"o\">.</span><span class=\"n\">year</span>\n    <span class=\"n\">month</span> <span class=\"o\">=</span> <span class=\"n\">date</span><span class=\"o\">.</span><span class=\"n\">month</span>\n    <span class=\"n\">day</span> <span class=\"o\">=</span> <span class=\"n\">date</span><span class=\"o\">.</span><span class=\"n\">day</span>\n\n    <span class=\"n\">isRunNian</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n    <span class=\"k\">if</span> <span class=\"n\">year</span> <span class=\"o\">%</span> <span class=\"mi\">4</span> <span class=\"o\">==</span> <span class=\"mi\">0</span> <span class=\"ow\">and</span> <span class=\"n\">year</span> <span class=\"o\">%</span> <span class=\"mi\">100</span> <span class=\"o\">!=</span> <span class=\"mi\">0</span> <span class=\"ow\">and</span> <span class=\"n\">year</span> <span class=\"o\">%</span> <span class=\"mi\">400</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n        <span class=\"n\">isRunNian</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">month</span> <span class=\"o\">&lt;</span> <span class=\"mi\">1</span> <span class=\"ow\">or</span> <span class=\"n\">month</span> <span class=\"o\">&gt;</span> <span class=\"mi\">12</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"kc\">False</span>\n\n    <span class=\"n\">pingnian_month</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">28</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">]</span>\n    <span class=\"n\">runnian_month</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">29</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"mi\">31</span><span class=\"p\">]</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">isRunNian</span><span class=\"p\">:</span>\n        <span class=\"k\">if</span> <span class=\"n\">day</span> <span class=\"o\">&lt;</span> <span class=\"mi\">1</span> <span class=\"ow\">or</span> <span class=\"n\">day</span> <span class=\"o\">&gt;</span> <span class=\"n\">pingnian_month</span><span class=\"p\">[</span><span class=\"n\">month</span><span class=\"p\">]:</span>\n            <span class=\"k\">return</span> <span class=\"kc\">False</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">if</span> <span class=\"n\">day</span> <span class=\"o\">&lt;</span> <span class=\"mi\">1</span> <span class=\"ow\">or</span> <span class=\"n\">day</span> <span class=\"o\">&gt;</span> <span class=\"n\">runnian_month</span><span class=\"p\">[</span><span class=\"n\">month</span><span class=\"p\">]:</span>\n            <span class=\"k\">return</span> <span class=\"kc\">False</span>\n\n    <span class=\"k\">return</span> <span class=\"kc\">True</span></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/train/EarlyStopping.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.train.EarlyStopping &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.train.EarlyStopping</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">from</span> <span class=\"nn\">scipy</span> <span class=\"k\">import</span> <span class=\"n\">stats</span>\n\n\n<div class=\"viewcode-block\" id=\"EarlyStopping\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">EarlyStopping</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Early stop if a span of newest records are not better than the current best record.</span>\n\n<span class=\"sd\">    Args:</span>\n<span class=\"sd\">        patience (int): The span of checked newest records.</span>\n\n<span class=\"sd\">    Attributes:</span>\n<span class=\"sd\">        __record_list (list): List of records.</span>\n<span class=\"sd\">        __best (float): The current best record.</span>\n<span class=\"sd\">        __patience (int): The span of checked newest records.</span>\n<span class=\"sd\">        __p (int): The number of newest records that are worse than the current best record.</span>\n\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">patience</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__record_list</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__best</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__patience</span> <span class=\"o\">=</span> <span class=\"n\">patience</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__p</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n\n<div class=\"viewcode-block\" id=\"EarlyStopping.stop\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.stop\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">stop</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">new_value</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Append the new record to the record list</span>\n<span class=\"sd\">        and check if the number of new records than are worse than the best records exceeds the limit.</span>\n\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            new_value (float): The new record generated by the newest model.</span>\n\n<span class=\"sd\">        Returns:</span>\n<span class=\"sd\">            bool: ``True`` if the number of new records than are worse than the best records exceeds the limit and</span>\n<span class=\"sd\">            triggers early stop, otherwise ``False``.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__record_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_value</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__best</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span> <span class=\"ow\">or</span> <span class=\"n\">new_value</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__best</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__best</span> <span class=\"o\">=</span> <span class=\"n\">new_value</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__p</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n            <span class=\"k\">return</span> <span class=\"kc\">False</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__p</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__patience</span><span class=\"p\">:</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__p</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span>\n                <span class=\"k\">return</span> <span class=\"kc\">False</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"k\">return</span> <span class=\"kc\">True</span></div></div>\n\n\n<div class=\"viewcode-block\" id=\"EarlyStoppingTTest\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">EarlyStoppingTTest</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Early Stop by t-test.</span>\n\n<span class=\"sd\">    T-test is a two-sided test for the null hypothesis that 2 independent samples</span>\n<span class=\"sd\">    have identical average (expected) values. This method takes two intervals according to ``length``</span>\n<span class=\"sd\">    in the record list and see if they have identical average values. If so, do early stop.</span>\n\n<span class=\"sd\">    Args:</span>\n<span class=\"sd\">        length (int): The length of checked interval.</span>\n<span class=\"sd\">        p_value_threshold (float): The p-value threshold to decide whether to do early stop.</span>\n\n<span class=\"sd\">    Attributes:</span>\n<span class=\"sd\">        __record_list (list): List of records.</span>\n<span class=\"sd\">        __best (float): The current best record.</span>\n<span class=\"sd\">        __test_length (int): The length of checked interval.</span>\n<span class=\"sd\">        __p_value_threshold (float): The p-value threshold to decide whether to do early stop.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">length</span><span class=\"p\">,</span> <span class=\"n\">p_value_threshold</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__record_list</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__best</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__test_length</span> <span class=\"o\">=</span> <span class=\"n\">length</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__p_value_threshold</span> <span class=\"o\">=</span> <span class=\"n\">p_value_threshold</span>\n\n<div class=\"viewcode-block\" id=\"EarlyStoppingTTest.stop\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.stop\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">stop</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">new_value</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Take two intervals in the record list to do t-test.</span>\n\n<span class=\"sd\">        Args:</span>\n<span class=\"sd\">            new_value (float): The new record generated by the newest model.</span>\n\n<span class=\"sd\">        Returns:</span>\n<span class=\"sd\">            bool: ``True`` if p value of t-test is smaller than threshold and</span>\n<span class=\"sd\">            triggers early stop, otherwise ``False``.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__record_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_value</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__record_list</span><span class=\"p\">)</span> <span class=\"o\">&gt;=</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__test_length</span> <span class=\"o\">*</span> <span class=\"mi\">2</span><span class=\"p\">):</span>\n            <span class=\"n\">lossTTest</span> <span class=\"o\">=</span> <span class=\"n\">stats</span><span class=\"o\">.</span><span class=\"n\">ttest_ind</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__record_list</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__test_length</span><span class=\"p\">:],</span>\n                                        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__record_list</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__test_length</span> <span class=\"o\">*</span> <span class=\"mi\">2</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__test_length</span><span class=\"p\">],</span> <span class=\"n\">equal_var</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n            <span class=\"n\">ttest</span> <span class=\"o\">=</span> <span class=\"n\">lossTTest</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n            <span class=\"n\">pValue</span> <span class=\"o\">=</span> <span class=\"n\">lossTTest</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n            <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;ttest:&#39;</span><span class=\"p\">,</span> <span class=\"n\">ttest</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pValue&#39;</span><span class=\"p\">,</span> <span class=\"n\">pValue</span><span class=\"p\">)</span>\n            <span class=\"k\">if</span> <span class=\"n\">pValue</span> <span class=\"o\">&gt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__p_value_threshold</span> <span class=\"ow\">or</span> <span class=\"n\">ttest</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n                <span class=\"k\">return</span> <span class=\"kc\">True</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"k\">return</span> <span class=\"kc\">False</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"kc\">False</span></div></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/train/MiniBatchTrain.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.train.MiniBatchTrain &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.train.MiniBatchTrain</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n\n<div class=\"viewcode-block\" id=\"MiniBatchTrain\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">MiniBatchTrain</span><span class=\"p\">():</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">Y</span><span class=\"p\">,</span> <span class=\"n\">batch_size</span><span class=\"p\">):</span>\n        <span class=\"c1\"># The first dimension of X should be sample size</span>\n        <span class=\"c1\"># The first dimension of Y should be sample size</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__X</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__Y</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">shuffle</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">Y</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span> <span class=\"o\">=</span> <span class=\"n\">batch_size</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_batch</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span> <span class=\"o\">/</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span><span class=\"p\">)</span> \\\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span> <span class=\"o\">==</span> <span class=\"mi\">0</span> <span class=\"k\">else</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span> <span class=\"o\">/</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n\n<div class=\"viewcode-block\" id=\"MiniBatchTrain.shuffle\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain.shuffle\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">shuffle</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">Y</span><span class=\"p\">):</span>\n        <span class=\"n\">xy</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">Y</span><span class=\"p\">))</span>\n        <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">random</span><span class=\"o\">.</span><span class=\"n\">shuffle</span><span class=\"p\">(</span><span class=\"n\">xy</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">xy</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">),</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">xy</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span></div>\n\n<div class=\"viewcode-block\" id=\"MiniBatchTrain.get_batch\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain.get_batch\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">get_batch</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span> <span class=\"o\">&lt;=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span><span class=\"p\">:</span>\n            <span class=\"n\">batch_x</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__X</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span><span class=\"p\">:</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span><span class=\"p\">]</span>\n            <span class=\"n\">batch_y</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__Y</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span><span class=\"p\">:</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span><span class=\"p\">]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">batch_x</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__X</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span><span class=\"p\">:</span> <span class=\"p\">]</span>\n            <span class=\"n\">batch_y</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__Y</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span><span class=\"p\">:</span> <span class=\"p\">]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">batch_x</span><span class=\"p\">,</span> <span class=\"n\">batch_y</span></div>\n\n<div class=\"viewcode-block\" id=\"MiniBatchTrain.restart\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain.restart\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">restart</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">=</span> <span class=\"mi\">0</span></div></div>\n\n\n<div class=\"viewcode-block\" id=\"MiniBatchTrainMultiData\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">MiniBatchTrainMultiData</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">,</span> <span class=\"n\">batch_size</span><span class=\"p\">,</span> <span class=\"n\">shuffle</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"n\">shuffle</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__data</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">shuffle</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__data</span> <span class=\"o\">=</span> <span class=\"n\">data</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__data</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span> <span class=\"o\">=</span> <span class=\"n\">batch_size</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_batch</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span> <span class=\"o\">/</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span><span class=\"p\">)</span> \\\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span> <span class=\"o\">==</span> <span class=\"mi\">0</span> <span class=\"k\">else</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span> <span class=\"o\">/</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n\n<div class=\"viewcode-block\" id=\"MiniBatchTrainMultiData.shuffle\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.shuffle\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">shuffle</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">):</span>\n        <span class=\"n\">middle</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">data</span><span class=\"p\">))</span>\n        <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">random</span><span class=\"o\">.</span><span class=\"n\">shuffle</span><span class=\"p\">(</span><span class=\"n\">middle</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">middle</span><span class=\"p\">))</span></div>\n\n<div class=\"viewcode-block\" id=\"MiniBatchTrainMultiData.get_batch\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.get_batch\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">get_batch</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span> <span class=\"o\">&lt;=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span><span class=\"p\">:</span>\n            <span class=\"n\">index</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span><span class=\"p\">]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">index</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__sample_size</span><span class=\"p\">]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n\n        <span class=\"k\">return</span> <span class=\"p\">[</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span> <span class=\"n\">index</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]])</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__data</span><span class=\"p\">]</span></div>\n\n<div class=\"viewcode-block\" id=\"MiniBatchTrainMultiData.restart\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.restart\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">restart</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">__batch_counter</span> <span class=\"o\">=</span> <span class=\"mi\">0</span></div></div>\n\n\n<div class=\"viewcode-block\" id=\"MiniBatchFeedDict\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">MiniBatchFeedDict</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">feed_dict</span><span class=\"p\">,</span> <span class=\"n\">sequence_length</span><span class=\"p\">,</span> <span class=\"n\">batch_size</span><span class=\"p\">,</span> <span class=\"n\">shuffle</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_sequence_length</span> <span class=\"o\">=</span> <span class=\"n\">sequence_length</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_size</span> <span class=\"o\">=</span> <span class=\"n\">batch_size</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dynamic_data_names</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dynamic_data_values</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_dict</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span> <span class=\"ow\">in</span> <span class=\"n\">feed_dict</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n            <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"n\">sequence_length</span><span class=\"p\">:</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dynamic_data_names</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">key</span><span class=\"p\">)</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dynamic_data_values</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_dict</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">shuffle</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dynamic_data_values</span> <span class=\"o\">=</span> <span class=\"n\">MiniBatchFeedDict</span><span class=\"o\">.</span><span class=\"n\">shuffle</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dynamic_data_values</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_counter</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_batch</span> <span class=\"o\">=</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_sequence_length</span> <span class=\"o\">/</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_size</span><span class=\"p\">)</span> \\\n            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_sequence_length</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_size</span> <span class=\"o\">==</span> <span class=\"mi\">0</span> <span class=\"k\">else</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_sequence_length</span> <span class=\"o\">/</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_size</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n\n<div class=\"viewcode-block\" id=\"MiniBatchFeedDict.get_batch\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.get_batch\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">get_batch</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_counter</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_size</span> <span class=\"o\">&lt;=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_sequence_length</span><span class=\"p\">:</span>\n            <span class=\"n\">index</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_counter</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_counter</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_size</span><span class=\"p\">]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_counter</span> <span class=\"o\">+=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_size</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">index</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_sequence_length</span><span class=\"o\">-</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_size</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_sequence_length</span><span class=\"p\">]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_counter</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dynamic_data_names</span><span class=\"p\">)):</span>\n            <span class=\"n\">key</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dynamic_data_names</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_dict</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_dynamic_data_values</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">index</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span><span class=\"n\">index</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]])</span>\n\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_dict</span></div>\n\n<div class=\"viewcode-block\" id=\"MiniBatchFeedDict.shuffle\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.shuffle\">[docs]</a>    <span class=\"nd\">@staticmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">shuffle</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">):</span>\n        <span class=\"n\">middle</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">data</span><span class=\"p\">))</span>\n        <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">random</span><span class=\"o\">.</span><span class=\"n\">shuffle</span><span class=\"p\">(</span><span class=\"n\">middle</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">middle</span><span class=\"p\">))</span></div>\n\n<div class=\"viewcode-block\" id=\"MiniBatchFeedDict.restart\"><a class=\"viewcode-back\" href=\"../../../UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.restart\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">restart</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_batch_counter</span> <span class=\"o\">=</span> <span class=\"mi\">0</span></div></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/utils/multi_threads.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.utils.multi_threads &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.utils.multi_threads</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">os</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">multiprocessing</span> <span class=\"k\">import</span> <span class=\"n\">Pool</span><span class=\"p\">,</span> <span class=\"n\">Manager</span>\n<span class=\"kn\">from</span> <span class=\"nn\">functools</span> <span class=\"k\">import</span> <span class=\"n\">reduce</span>\n\n\n<span class=\"c1\"># (my_rank, n_jobs, dataList, resultHandleFunction, parameterList)</span>\n<div class=\"viewcode-block\" id=\"multiple_process\"><a class=\"viewcode-back\" href=\"../../../UCTB.utils.html#UCTB.utils.multi_threads.multiple_process\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">multiple_process</span><span class=\"p\">(</span><span class=\"n\">distribute_list</span><span class=\"p\">,</span> <span class=\"n\">partition_func</span><span class=\"p\">,</span> <span class=\"n\">task_func</span><span class=\"p\">,</span> <span class=\"n\">n_jobs</span><span class=\"p\">,</span> <span class=\"n\">reduce_func</span><span class=\"p\">,</span> <span class=\"n\">parameters</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"n\">callable</span><span class=\"p\">(</span><span class=\"n\">partition_func</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">callable</span><span class=\"p\">(</span><span class=\"n\">task_func</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">callable</span><span class=\"p\">(</span><span class=\"n\">reduce_func</span><span class=\"p\">):</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Parent process </span><span class=\"si\">%s</span><span class=\"s1\">.&#39;</span> <span class=\"o\">%</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">getpid</span><span class=\"p\">())</span>\n\n        <span class=\"n\">manager</span> <span class=\"o\">=</span> <span class=\"n\">Manager</span><span class=\"p\">()</span>\n        <span class=\"n\">share_queue</span> <span class=\"o\">=</span> <span class=\"n\">manager</span><span class=\"o\">.</span><span class=\"n\">Queue</span><span class=\"p\">()</span>\n        <span class=\"n\">locker</span> <span class=\"o\">=</span> <span class=\"n\">manager</span><span class=\"o\">.</span><span class=\"n\">Lock</span><span class=\"p\">()</span>\n\n        <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">Pool</span><span class=\"p\">()</span>\n        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">n_jobs</span><span class=\"p\">):</span>\n            <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">apply_async</span><span class=\"p\">(</span><span class=\"n\">task_func</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"n\">share_queue</span><span class=\"p\">,</span> <span class=\"n\">locker</span><span class=\"p\">,</span> <span class=\"n\">partition_func</span><span class=\"p\">(</span><span class=\"n\">distribute_list</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">n_jobs</span><span class=\"p\">),</span>\n                                           <span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">parameters</span><span class=\"p\">,))</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Waiting for all sub_processes done...&#39;</span><span class=\"p\">)</span>\n        <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">close</span><span class=\"p\">()</span>\n        <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">()</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;All sub_processes done.&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">result_list</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"k\">while</span> <span class=\"ow\">not</span> <span class=\"n\">share_queue</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">():</span>\n            <span class=\"n\">result_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">share_queue</span><span class=\"o\">.</span><span class=\"n\">get_nowait</span><span class=\"p\">())</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">reduce</span><span class=\"p\">(</span><span class=\"n\">reduce_func</span><span class=\"p\">,</span> <span class=\"n\">result_list</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Parameter error&#39;</span><span class=\"p\">)</span></div>\n\n\n<span class=\"c1\"># Example</span>\n<div class=\"viewcode-block\" id=\"task\"><a class=\"viewcode-back\" href=\"../../../UCTB.utils.html#UCTB.utils.multi_threads.task\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">task</span><span class=\"p\">(</span><span class=\"n\">share_queue</span><span class=\"p\">,</span> <span class=\"n\">locker</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">,</span> <span class=\"n\">parameters</span><span class=\"p\">):</span>\n\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Child process </span><span class=\"si\">%s</span><span class=\"s1\"> with pid </span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">parameters</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">getpid</span><span class=\"p\">()))</span>\n\n    <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"nb\">sum</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n\n    <span class=\"n\">locker</span><span class=\"o\">.</span><span class=\"n\">acquire</span><span class=\"p\">()</span>\n    <span class=\"n\">share_queue</span><span class=\"o\">.</span><span class=\"n\">put</span><span class=\"p\">(</span><span class=\"n\">result</span><span class=\"p\">)</span>\n    <span class=\"n\">locker</span><span class=\"o\">.</span><span class=\"n\">release</span><span class=\"p\">()</span></div>\n\n\n<span class=\"k\">if</span> <span class=\"vm\">__name__</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;__main__&quot;</span><span class=\"p\">:</span>\n\n    <span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">e</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">1000000</span><span class=\"p\">)]</span>\n\n    <span class=\"n\">n_job</span> <span class=\"o\">=</span> <span class=\"mi\">4</span>\n\n    <span class=\"n\">sum_result</span> <span class=\"o\">=</span> \\\n        <span class=\"n\">multiple_process</span><span class=\"p\">(</span><span class=\"n\">distribute_list</span><span class=\"o\">=</span><span class=\"n\">data</span><span class=\"p\">,</span>\n                         <span class=\"n\">partition_func</span><span class=\"o\">=</span><span class=\"k\">lambda</span> <span class=\"n\">data</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">n_job</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"n\">e</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">))</span> <span class=\"k\">if</span> <span class=\"n\">e</span> <span class=\"o\">%</span> <span class=\"n\">n_job</span> <span class=\"o\">==</span> <span class=\"n\">i</span><span class=\"p\">],</span>\n                         <span class=\"n\">task_func</span><span class=\"o\">=</span><span class=\"n\">task</span><span class=\"p\">,</span> <span class=\"n\">n_jobs</span><span class=\"o\">=</span><span class=\"n\">n_job</span><span class=\"p\">,</span> <span class=\"n\">reduce_func</span><span class=\"o\">=</span><span class=\"k\">lambda</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">:</span> <span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">y</span><span class=\"p\">,</span> <span class=\"n\">parameters</span><span class=\"o\">=</span><span class=\"p\">[])</span>\n\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Result&#39;</span><span class=\"p\">,</span> <span class=\"n\">sum_result</span><span class=\"p\">)</span>\n\n\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/UCTB/utils/st_map.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>UCTB.utils.st_map &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for UCTB.utils.st_map</h1><div class=\"highlight\"><pre>\n<span></span>\n<span class=\"c1\"># Plot saptial-temporal map</span>\n<div class=\"viewcode-block\" id=\"st_map\"><a class=\"viewcode-back\" href=\"../../../UCTB.utils.html#UCTB.utils.st_map.st_map\">[docs]</a><span class=\"k\">def</span> <span class=\"nf\">st_map</span><span class=\"p\">(</span><span class=\"n\">lat</span><span class=\"p\">,</span> <span class=\"n\">lng</span><span class=\"p\">,</span> <span class=\"n\">build_order</span><span class=\"p\">,</span> <span class=\"n\">meta_info</span><span class=\"p\">,</span> <span class=\"n\">file_name</span><span class=\"p\">,</span>\n           <span class=\"n\">zoom</span><span class=\"o\">=</span><span class=\"mi\">11</span><span class=\"p\">,</span> <span class=\"n\">style</span><span class=\"o\">=</span><span class=\"s1\">&#39;light&#39;</span><span class=\"p\">):</span>\n\n    <span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n    <span class=\"kn\">import</span> <span class=\"nn\">plotly</span>\n    <span class=\"kn\">from</span> <span class=\"nn\">plotly.graph_objs</span> <span class=\"k\">import</span> <span class=\"n\">Scattermapbox</span><span class=\"p\">,</span> <span class=\"n\">Layout</span>\n\n    <span class=\"n\">mapboxAccessToken</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;pk.eyJ1Ijoicm1ldGZjIiwiYSI6ImNqN2JjN3l3NjBxc3MycXAzNnh6M2oxbGoifQ.WFNVzFwNJ9ILp0Jxa03mCQ&quot;</span>\n\n    <span class=\"n\">bikeStations</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">Scattermapbox</span><span class=\"p\">(</span>\n        <span class=\"n\">lon</span><span class=\"o\">=</span><span class=\"n\">lng</span><span class=\"p\">,</span>\n        <span class=\"n\">lat</span><span class=\"o\">=</span><span class=\"n\">lat</span><span class=\"p\">,</span>\n        <span class=\"n\">text</span><span class=\"o\">=</span><span class=\"n\">meta_info</span><span class=\"p\">,</span>\n        <span class=\"n\">mode</span><span class=\"o\">=</span><span class=\"s1\">&#39;markers&#39;</span><span class=\"p\">,</span>\n        <span class=\"n\">marker</span><span class=\"o\">=</span><span class=\"nb\">dict</span><span class=\"p\">(</span>\n            <span class=\"n\">size</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span>\n            <span class=\"n\">color</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;rgb(</span><span class=\"si\">%s</span><span class=\"s1\">, </span><span class=\"si\">%s</span><span class=\"s1\">, </span><span class=\"si\">%s</span><span class=\"s1\">)&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"mi\">255</span><span class=\"p\">,</span>\n                                        <span class=\"mi\">195</span> <span class=\"o\">-</span> <span class=\"n\">e</span> <span class=\"o\">*</span> <span class=\"mi\">195</span> <span class=\"o\">/</span> <span class=\"nb\">max</span><span class=\"p\">(</span><span class=\"n\">build_order</span><span class=\"p\">),</span>\n                                        <span class=\"mi\">195</span> <span class=\"o\">-</span> <span class=\"n\">e</span> <span class=\"o\">*</span> <span class=\"mi\">195</span> <span class=\"o\">/</span> <span class=\"nb\">max</span><span class=\"p\">(</span><span class=\"n\">build_order</span><span class=\"p\">))</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">build_order</span><span class=\"p\">],</span>\n            <span class=\"n\">opacity</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n        <span class=\"p\">))]</span>\n    \n    <span class=\"n\">layout</span> <span class=\"o\">=</span> <span class=\"n\">Layout</span><span class=\"p\">(</span>\n        <span class=\"n\">title</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike Station Location &amp; The latest built stations with deeper color&#39;</span><span class=\"p\">,</span>\n        <span class=\"n\">autosize</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n        <span class=\"n\">hovermode</span><span class=\"o\">=</span><span class=\"s1\">&#39;closest&#39;</span><span class=\"p\">,</span>\n        <span class=\"n\">showlegend</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span>\n        <span class=\"n\">mapbox</span><span class=\"o\">=</span><span class=\"nb\">dict</span><span class=\"p\">(</span>\n            <span class=\"n\">accesstoken</span><span class=\"o\">=</span><span class=\"n\">mapboxAccessToken</span><span class=\"p\">,</span>\n            <span class=\"n\">bearing</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n            <span class=\"n\">center</span><span class=\"o\">=</span><span class=\"nb\">dict</span><span class=\"p\">(</span>\n                <span class=\"n\">lat</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">median</span><span class=\"p\">(</span><span class=\"n\">lat</span><span class=\"p\">),</span>\n                <span class=\"n\">lon</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">median</span><span class=\"p\">(</span><span class=\"n\">lng</span><span class=\"p\">)</span>\n            <span class=\"p\">),</span>\n            <span class=\"n\">pitch</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n            <span class=\"n\">zoom</span><span class=\"o\">=</span><span class=\"n\">zoom</span><span class=\"p\">,</span>\n            <span class=\"n\">style</span><span class=\"o\">=</span><span class=\"n\">style</span>\n        <span class=\"p\">),</span>\n    <span class=\"p\">)</span>\n\n    <span class=\"n\">fig</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"o\">=</span><span class=\"n\">bikeStations</span><span class=\"p\">,</span> <span class=\"n\">layout</span><span class=\"o\">=</span><span class=\"n\">layout</span><span class=\"p\">)</span>\n    <span class=\"n\">plotly</span><span class=\"o\">.</span><span class=\"n\">offline</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">fig</span><span class=\"p\">,</span> <span class=\"n\">filename</span><span class=\"o\">=</span><span class=\"n\">file_name</span><span class=\"p\">)</span></div>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/index.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Overview: module code &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../\" src=\"../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../index.html\">UCTB  documentation</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>All modules for which code is available</h1>\n<ul><li><a href=\"UCTB/dataset/data_loader.html\">UCTB.dataset.data_loader</a></li>\n<li><a href=\"UCTB/dataset/dataset.html\">UCTB.dataset.dataset</a></li>\n<li><a href=\"UCTB/evaluation/metric.html\">UCTB.evaluation.metric</a></li>\n<li><a href=\"UCTB/model/ARIMA.html\">UCTB.model.ARIMA</a></li>\n<li><a href=\"UCTB/model/DCRNN.html\">UCTB.model.DCRNN</a></li>\n<li><a href=\"UCTB/model/DeepST.html\">UCTB.model.DeepST</a></li>\n<li><a href=\"UCTB/model/GeoMAN.html\">UCTB.model.GeoMAN</a></li>\n<li><a href=\"UCTB/model/HM.html\">UCTB.model.HM</a></li>\n<li><a href=\"UCTB/model/HMM.html\">UCTB.model.HMM</a></li>\n<li><a href=\"UCTB/model/STMeta.html\">UCTB.model.STMeta</a></li>\n<li><a href=\"UCTB/model/ST_MGCN.html\">UCTB.model.ST_MGCN</a></li>\n<li><a href=\"UCTB/model/ST_ResNet.html\">UCTB.model.ST_ResNet</a></li>\n<li><a href=\"UCTB/model/XGBoost.html\">UCTB.model.XGBoost</a></li>\n<li><a href=\"UCTB/model_unit/BaseModel.html\">UCTB.model_unit.BaseModel</a></li>\n<li><a href=\"UCTB/model_unit/DCRNN_CELL.html\">UCTB.model_unit.DCRNN_CELL</a></li>\n<li><a href=\"UCTB/model_unit/GraphModelLayers.html\">UCTB.model_unit.GraphModelLayers</a></li>\n<li><a href=\"UCTB/model_unit/ST_RNN.html\">UCTB.model_unit.ST_RNN</a></li>\n<li><a href=\"UCTB/preprocess/preprocessor.html\">UCTB.preprocess.preprocessor</a></li>\n<li><a href=\"UCTB/preprocess/time_utils.html\">UCTB.preprocess.time_utils</a></li>\n<li><a href=\"UCTB/train/EarlyStopping.html\">UCTB.train.EarlyStopping</a></li>\n<li><a href=\"UCTB/train/MiniBatchTrain.html\">UCTB.train.MiniBatchTrain</a></li>\n<li><a href=\"UCTB/utils/multi_threads.html\">UCTB.utils.multi_threads</a></li>\n<li><a href=\"UCTB/utils/st_map.html\">UCTB.utils.st_map</a></li>\n<li><a href=\"tensorflow/python/keras/utils/tf_utils.html\">tensorflow.python.keras.utils.tf_utils</a></li>\n</ul>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../index.html\">UCTB  documentation</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/tensorflow/python/keras/utils/tf_utils.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>tensorflow.python.keras.utils.tf_utils &#8212; UCTB  documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../../../_static/nature.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../../../\" src=\"../../../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../../../search.html\" /> \n  </head><body>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../../../genindex.html\" title=\"General Index\"\n             accesskey=\"I\">index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../../../index.html\" accesskey=\"U\">Module code</a> &#187;</li> \n      </ul>\n    </div>  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for tensorflow.python.keras.utils.tf_utils</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"c1\"># Copyright 2018 The TensorFlow Authors. All Rights Reserved.</span>\n<span class=\"c1\">#</span>\n<span class=\"c1\"># Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span>\n<span class=\"c1\"># you may not use this file except in compliance with the License.</span>\n<span class=\"c1\"># You may obtain a copy of the License at</span>\n<span class=\"c1\">#</span>\n<span class=\"c1\">#     http://www.apache.org/licenses/LICENSE-2.0</span>\n<span class=\"c1\">#</span>\n<span class=\"c1\"># Unless required by applicable law or agreed to in writing, software</span>\n<span class=\"c1\"># distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span>\n<span class=\"c1\"># WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>\n<span class=\"c1\"># See the License for the specific language governing permissions and</span>\n<span class=\"c1\"># limitations under the License.</span>\n<span class=\"c1\"># ==============================================================================</span>\n<span class=\"sd\">&quot;&quot;&quot;TensorFlow-related utilities.&quot;&quot;&quot;</span>\n<span class=\"kn\">from</span> <span class=\"nn\">__future__</span> <span class=\"k\">import</span> <span class=\"n\">absolute_import</span>\n<span class=\"kn\">from</span> <span class=\"nn\">__future__</span> <span class=\"k\">import</span> <span class=\"n\">division</span>\n<span class=\"kn\">from</span> <span class=\"nn\">__future__</span> <span class=\"k\">import</span> <span class=\"n\">print_function</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.eager</span> <span class=\"k\">import</span> <span class=\"n\">context</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.framework</span> <span class=\"k\">import</span> <span class=\"n\">ops</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.framework</span> <span class=\"k\">import</span> <span class=\"n\">smart_cond</span> <span class=\"k\">as</span> <span class=\"n\">smart_module</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.framework</span> <span class=\"k\">import</span> <span class=\"n\">sparse_tensor</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.framework</span> <span class=\"k\">import</span> <span class=\"n\">tensor_shape</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.framework</span> <span class=\"k\">import</span> <span class=\"n\">tensor_util</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.ops</span> <span class=\"k\">import</span> <span class=\"n\">control_flow_ops</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.ops</span> <span class=\"k\">import</span> <span class=\"n\">variables</span>\n<span class=\"kn\">from</span> <span class=\"nn\">tensorflow.python.util</span> <span class=\"k\">import</span> <span class=\"n\">nest</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">smart_cond</span><span class=\"p\">(</span><span class=\"n\">pred</span><span class=\"p\">,</span> <span class=\"n\">true_fn</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">false_fn</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n  <span class=\"sd\">&quot;&quot;&quot;Return either `true_fn()` if predicate `pred` is true else `false_fn()`.</span>\n\n<span class=\"sd\">  If `pred` is a bool or has a constant value, we return either `true_fn()`</span>\n<span class=\"sd\">  or `false_fn()`, otherwise we use `tf.cond` to dynamically route to both.</span>\n\n<span class=\"sd\">  Arguments:</span>\n<span class=\"sd\">    pred: A scalar determining whether to return the result of `true_fn` or</span>\n<span class=\"sd\">      `false_fn`.</span>\n<span class=\"sd\">    true_fn: The callable to be performed if pred is true.</span>\n<span class=\"sd\">    false_fn: The callable to be performed if pred is false.</span>\n<span class=\"sd\">    name: Optional name prefix when using `tf.cond`.</span>\n\n<span class=\"sd\">  Returns:</span>\n<span class=\"sd\">    Tensors returned by the call to either `true_fn` or `false_fn`.</span>\n\n<span class=\"sd\">  Raises:</span>\n<span class=\"sd\">    TypeError: If `true_fn` or `false_fn` is not callable.</span>\n<span class=\"sd\">  &quot;&quot;&quot;</span>\n  <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">pred</span><span class=\"p\">,</span> <span class=\"n\">variables</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">control_flow_ops</span><span class=\"o\">.</span><span class=\"n\">cond</span><span class=\"p\">(</span>\n        <span class=\"n\">pred</span><span class=\"p\">,</span> <span class=\"n\">true_fn</span><span class=\"o\">=</span><span class=\"n\">true_fn</span><span class=\"p\">,</span> <span class=\"n\">false_fn</span><span class=\"o\">=</span><span class=\"n\">false_fn</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"n\">name</span><span class=\"p\">)</span>\n  <span class=\"k\">return</span> <span class=\"n\">smart_module</span><span class=\"o\">.</span><span class=\"n\">smart_cond</span><span class=\"p\">(</span>\n      <span class=\"n\">pred</span><span class=\"p\">,</span> <span class=\"n\">true_fn</span><span class=\"o\">=</span><span class=\"n\">true_fn</span><span class=\"p\">,</span> <span class=\"n\">false_fn</span><span class=\"o\">=</span><span class=\"n\">false_fn</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"n\">name</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">constant_value</span><span class=\"p\">(</span><span class=\"n\">pred</span><span class=\"p\">):</span>\n  <span class=\"sd\">&quot;&quot;&quot;Return the bool value for `pred`, or None if `pred` had a dynamic value.</span>\n\n<span class=\"sd\">  Arguments:</span>\n<span class=\"sd\">    pred: A scalar, either a Python bool or a TensorFlow boolean variable</span>\n<span class=\"sd\">      or tensor, or the Python integer 1 or 0.</span>\n\n<span class=\"sd\">  Returns:</span>\n<span class=\"sd\">    True or False if `pred` has a constant boolean value, None otherwise.</span>\n\n<span class=\"sd\">  Raises:</span>\n<span class=\"sd\">    TypeError: If `pred` is not a Variable, Tensor or bool, or Python</span>\n<span class=\"sd\">      integer 1 or 0.</span>\n<span class=\"sd\">  &quot;&quot;&quot;</span>\n  <span class=\"c1\"># Allow integer booleans.</span>\n  <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">pred</span><span class=\"p\">,</span> <span class=\"nb\">int</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"n\">pred</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n      <span class=\"n\">pred</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n    <span class=\"k\">elif</span> <span class=\"n\">pred</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n      <span class=\"n\">pred</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n\n  <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">pred</span><span class=\"p\">,</span> <span class=\"n\">variables</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"kc\">None</span>\n  <span class=\"k\">return</span> <span class=\"n\">smart_module</span><span class=\"o\">.</span><span class=\"n\">smart_constant_value</span><span class=\"p\">(</span><span class=\"n\">pred</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">is_tensor_or_tensor_list</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"p\">):</span>\n  <span class=\"n\">v</span> <span class=\"o\">=</span> <span class=\"n\">nest</span><span class=\"o\">.</span><span class=\"n\">flatten</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"p\">)</span>\n  <span class=\"k\">if</span> <span class=\"n\">v</span> <span class=\"ow\">and</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">ops</span><span class=\"o\">.</span><span class=\"n\">Tensor</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"kc\">True</span>\n  <span class=\"k\">else</span><span class=\"p\">:</span>\n    <span class=\"k\">return</span> <span class=\"kc\">False</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">get_reachable_from_inputs</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">targets</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n  <span class=\"sd\">&quot;&quot;&quot;Returns the set of tensors/ops reachable from `inputs`.</span>\n\n<span class=\"sd\">  Stops if all targets have been found (target is optional).</span>\n\n<span class=\"sd\">  Only valid in Symbolic mode, not Eager mode.</span>\n\n<span class=\"sd\">  Args:</span>\n<span class=\"sd\">    inputs: List of tensors.</span>\n<span class=\"sd\">    targets: List of tensors.</span>\n\n<span class=\"sd\">  Returns:</span>\n<span class=\"sd\">    A set of tensors reachable from the inputs (includes the inputs themselves).</span>\n<span class=\"sd\">  &quot;&quot;&quot;</span>\n  <span class=\"n\">reachable</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">)</span>\n  <span class=\"k\">if</span> <span class=\"n\">targets</span><span class=\"p\">:</span>\n    <span class=\"n\">targets</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">targets</span><span class=\"p\">)</span>\n  <span class=\"n\">queue</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[:]</span>\n\n  <span class=\"k\">while</span> <span class=\"n\">queue</span><span class=\"p\">:</span>\n    <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">queue</span><span class=\"o\">.</span><span class=\"n\">pop</span><span class=\"p\">()</span>\n    <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">ops</span><span class=\"o\">.</span><span class=\"n\">Operation</span><span class=\"p\">):</span>\n      <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"n\">x</span><span class=\"o\">.</span><span class=\"n\">outputs</span><span class=\"p\">[:]</span> <span class=\"ow\">or</span> <span class=\"p\">[]</span>\n      <span class=\"n\">outputs</span> <span class=\"o\">+=</span> <span class=\"n\">x</span><span class=\"o\">.</span><span class=\"n\">_control_outputs</span>  <span class=\"c1\"># pylint: disable=protected-access</span>\n    <span class=\"k\">elif</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">variables</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">):</span>\n      <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">x</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">]</span>\n    <span class=\"k\">elif</span> <span class=\"n\">tensor_util</span><span class=\"o\">.</span><span class=\"n\">is_tensor</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">):</span>\n      <span class=\"n\">outputs</span> <span class=\"o\">=</span> <span class=\"n\">x</span><span class=\"o\">.</span><span class=\"n\">consumers</span><span class=\"p\">()</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n      <span class=\"k\">raise</span> <span class=\"ne\">TypeError</span><span class=\"p\">(</span><span class=\"s1\">&#39;Expected Operation, Variable, or Tensor, got &#39;</span> <span class=\"o\">+</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">))</span>\n\n    <span class=\"k\">for</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"n\">outputs</span><span class=\"p\">:</span>\n      <span class=\"k\">if</span> <span class=\"n\">y</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">reachable</span><span class=\"p\">:</span>\n        <span class=\"n\">reachable</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">y</span><span class=\"p\">)</span>\n        <span class=\"n\">queue</span><span class=\"o\">.</span><span class=\"n\">insert</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">)</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">targets</span> <span class=\"ow\">and</span> <span class=\"n\">targets</span><span class=\"o\">.</span><span class=\"n\">issubset</span><span class=\"p\">(</span><span class=\"n\">reachable</span><span class=\"p\">):</span>\n      <span class=\"k\">return</span> <span class=\"n\">reachable</span>\n  <span class=\"k\">return</span> <span class=\"n\">reachable</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">shape_type_conversion</span><span class=\"p\">(</span><span class=\"n\">fn</span><span class=\"p\">):</span>\n  <span class=\"sd\">&quot;&quot;&quot;Decorator that handles tuple/TensorShape conversion.</span>\n\n<span class=\"sd\">  Used in `compute_output_shape` and `build`.</span>\n\n<span class=\"sd\">  Arguments:</span>\n<span class=\"sd\">    fn: function to wrap.</span>\n\n<span class=\"sd\">  Returns:</span>\n<span class=\"sd\">    Wrapped function.</span>\n<span class=\"sd\">  &quot;&quot;&quot;</span>\n\n  <span class=\"k\">def</span> <span class=\"nf\">wrapper</span><span class=\"p\">(</span><span class=\"n\">instance</span><span class=\"p\">,</span> <span class=\"n\">input_shape</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"n\">input_shape</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n      <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">input_shape</span><span class=\"p\">,</span> <span class=\"nb\">list</span><span class=\"p\">):</span>\n        <span class=\"n\">input_shape</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n            <span class=\"nb\">tuple</span><span class=\"p\">(</span><span class=\"n\">tensor_shape</span><span class=\"o\">.</span><span class=\"n\">TensorShape</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">as_list</span><span class=\"p\">())</span> <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"n\">input_shape</span><span class=\"p\">]</span>\n      <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">input_shape</span> <span class=\"o\">=</span> <span class=\"nb\">tuple</span><span class=\"p\">(</span><span class=\"n\">tensor_shape</span><span class=\"o\">.</span><span class=\"n\">TensorShape</span><span class=\"p\">(</span><span class=\"n\">input_shape</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">as_list</span><span class=\"p\">())</span>\n    <span class=\"n\">output_shape</span> <span class=\"o\">=</span> <span class=\"n\">fn</span><span class=\"p\">(</span><span class=\"n\">instance</span><span class=\"p\">,</span> <span class=\"n\">input_shape</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">output_shape</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n      <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">output_shape</span><span class=\"p\">,</span> <span class=\"nb\">list</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"p\">[</span><span class=\"n\">tensor_shape</span><span class=\"o\">.</span><span class=\"n\">TensorShape</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"n\">output_shape</span><span class=\"p\">]</span>\n      <span class=\"k\">return</span> <span class=\"n\">tensor_shape</span><span class=\"o\">.</span><span class=\"n\">TensorShape</span><span class=\"p\">(</span><span class=\"n\">output_shape</span><span class=\"p\">)</span>\n\n  <span class=\"k\">return</span> <span class=\"n\">wrapper</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">are_all_symbolic_tensors</span><span class=\"p\">(</span><span class=\"n\">tensors</span><span class=\"p\">):</span>\n  <span class=\"k\">return</span> <span class=\"nb\">all</span><span class=\"p\">(</span><span class=\"n\">is_symbolic_tensor</span><span class=\"p\">(</span><span class=\"n\">tensor</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">tensor</span> <span class=\"ow\">in</span> <span class=\"n\">tensors</span><span class=\"p\">)</span>\n\n\n<span class=\"n\">_user_convertible_tensor_types</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">()</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">is_symbolic_tensor</span><span class=\"p\">(</span><span class=\"n\">tensor</span><span class=\"p\">):</span>\n  <span class=\"sd\">&quot;&quot;&quot;Returns whether a tensor is symbolic (from a TF graph) or an eager tensor.</span>\n\n<span class=\"sd\">  A Variable can be seen as either: it is considered symbolic</span>\n<span class=\"sd\">  when we are in a graph scope, and eager when we are in an eager scope.</span>\n\n<span class=\"sd\">  Arguments:</span>\n<span class=\"sd\">    tensor: A tensor instance to test.</span>\n\n<span class=\"sd\">  Returns:</span>\n<span class=\"sd\">    True for symbolic tensors, False for eager tensors.</span>\n<span class=\"sd\">  &quot;&quot;&quot;</span>\n  <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">tensor</span><span class=\"p\">,</span> <span class=\"n\">variables</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"ow\">not</span> <span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">executing_eagerly</span><span class=\"p\">()</span>\n  <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">tensor</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">ops</span><span class=\"o\">.</span><span class=\"n\">Tensor</span><span class=\"p\">,</span> <span class=\"n\">sparse_tensor</span><span class=\"o\">.</span><span class=\"n\">SparseTensor</span><span class=\"p\">)):</span>\n    <span class=\"k\">return</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">tensor</span><span class=\"p\">,</span> <span class=\"s1\">&#39;graph&#39;</span><span class=\"p\">)</span>\n  <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">tensor</span><span class=\"p\">,</span> <span class=\"nb\">tuple</span><span class=\"p\">(</span><span class=\"n\">_user_convertible_tensor_types</span><span class=\"p\">)):</span>\n    <span class=\"k\">return</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">ops</span><span class=\"o\">.</span><span class=\"n\">convert_to_tensor</span><span class=\"p\">(</span><span class=\"n\">tensor</span><span class=\"p\">),</span> <span class=\"s1\">&#39;graph&#39;</span><span class=\"p\">)</span>\n  <span class=\"k\">return</span> <span class=\"kc\">False</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">register_symbolic_tensor_type</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">):</span>\n  <span class=\"sd\">&quot;&quot;&quot;Allows users to specify types regarded as symbolic `Tensor`s.</span>\n\n<span class=\"sd\">  Used in conjunction with `tf.register_tensor_conversion_function`, calling</span>\n<span class=\"sd\">  `tf.keras.utils.register_symbolic_tensor_type(cls)` allows non-`Tensor`</span>\n<span class=\"sd\">  objects to be plumbed through Keras layers.</span>\n\n<span class=\"sd\">  Example:</span>\n\n<span class=\"sd\">  ```python</span>\n<span class=\"sd\">  # One-time setup.</span>\n<span class=\"sd\">  class Foo(object):</span>\n<span class=\"sd\">    def __init__(self, input_):</span>\n<span class=\"sd\">      self._input = input_</span>\n<span class=\"sd\">    def value(self):</span>\n<span class=\"sd\">      return tf.constant(42.)</span>\n\n<span class=\"sd\">  tf.register_tensor_conversion_function(</span>\n<span class=\"sd\">      Foo, lambda x, *args, **kwargs: x.value())</span>\n\n<span class=\"sd\">  tf.keras.utils.register_symbolic_tensor_type(Foo)</span>\n\n<span class=\"sd\">  # User-land.</span>\n<span class=\"sd\">  layer = tf.keras.layers.Lambda(lambda input_: Foo(input_))</span>\n<span class=\"sd\">  ```</span>\n\n<span class=\"sd\">  Arguments:</span>\n<span class=\"sd\">    cls: A `class` type which shall be regarded as a symbolic `Tensor`.</span>\n<span class=\"sd\">  &quot;&quot;&quot;</span>\n  <span class=\"k\">global</span> <span class=\"n\">_user_convertible_tensor_types</span>\n  <span class=\"n\">_user_convertible_tensor_types</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">)</span>\n</pre></div>\n\n          </div>\n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"related\" role=\"navigation\" aria-label=\"related navigation\">\n      <h3>Navigation</h3>\n      <ul>\n        <li class=\"right\" style=\"margin-right: 10px\">\n          <a href=\"../../../../../genindex.html\" title=\"General Index\"\n             >index</a></li>\n        <li class=\"right\" >\n          <a href=\"../../../../../py-modindex.html\" title=\"Python Module Index\"\n             >modules</a> |</li>\n        <li class=\"nav-item nav-item-0\"><a href=\"../../../../../index.html\">UCTB  documentation</a> &#187;</li>\n          <li class=\"nav-item nav-item-1\"><a href=\"../../../../index.html\" >Module code</a> &#187;</li> \n      </ul>\n    </div>\n    <div class=\"footer\" role=\"contentinfo\">\n        &#169; Copyright 2019, Di Chai, Leye Wang, Jin Xu, Wenjie Yang, Liyue Chen.\n      Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> 2.2.1.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "docs/_sources/APIReference.rst.txt",
    "content": "API Reference\n====================\n\n.. toctree::\n\n    UCTB.dataset.rst\n\n    UCTB.preprocess.rst\n\n    UCTB.model_unit.rst\n\n    UCTB.model.rst\n\n    UCTB.evaluation.rst\n\n    UCTB.train.rst\n\n    UCTB.utils.rst"
  },
  {
    "path": "docs/_sources/UCTB.dataset.rst.txt",
    "content": "UCTB.dataset package\n====================\n\nUCTB.dataset.data\\_loader module\n--------------------------------\n\n.. automodule:: UCTB.dataset.data_loader\n   :members:\n   :show-inheritance:\n\nUCTB.dataset.dataset module\n---------------------------\n\n.. automodule:: UCTB.dataset.dataset\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/_sources/UCTB.evaluation.rst.txt",
    "content": "UCTB.evaluation package\n=======================\n\n\nUCTB.evaluation.metric module\n-----------------------------\n\n.. automodule:: UCTB.evaluation.metric\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/_sources/UCTB.model.rst.txt",
    "content": "UCTB.model package\n==================\n\nUCTB.model.ARIMA module\n-----------------------\n\n.. automodule:: UCTB.model.ARIMA\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.DCRNN module\n-----------------------\n\n.. automodule:: UCTB.model.DCRNN\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.DeepST module\n------------------------\n\n.. automodule:: UCTB.model.DeepST\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.GeoMAN module\n------------------------\n\n.. automodule:: UCTB.model.GeoMAN\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.HM module\n--------------------\n\n.. automodule:: UCTB.model.HM\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.STMeta module\n------------------------\n\n.. automodule:: UCTB.model.STMeta\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.ST\\_MGCN module\n--------------------------\n\n.. automodule:: UCTB.model.ST_MGCN\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.ST\\_ResNet module\n----------------------------\n\n.. automodule:: UCTB.model.ST_ResNet\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.XGBoost module\n-------------------------\n\n.. automodule:: UCTB.model.XGBoost\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.AGCRN module\n-------------------------\n\n.. automodule:: UCTB.model.AGCRN\n   :members:\n   :show-inheritance:\n\nUCTB.model.ASTGCN module\n-------------------------\n\n.. automodule:: UCTB.model.ASTGCN\n   :members:\n   :show-inheritance:\n\nUCTB.model.GMAN module\n-------------------------\n\n.. automodule:: UCTB.model.GMAN\n   :members:\n   :show-inheritance:\n\nUCTB.model.GraphWaveNet module\n-------------------------\n\n.. automodule:: UCTB.model.GraphWaveNet\n   :members:\n   :show-inheritance:\n\nUCTB.model.STGCN module\n-------------------------\n\n.. automodule:: UCTB.model.STGCN\n   :members:\n   :show-inheritance:\n\nUCTB.model.STSGCN module\n-------------------------\n\n.. automodule:: UCTB.model.STSGCN\n   :members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/_sources/UCTB.model_unit.rst.txt",
    "content": "UCTB.model\\_unit package\n========================\n\n\nUCTB.model\\_unit.BaseModel module\n---------------------------------\n\n.. automodule:: UCTB.model_unit.BaseModel\n   :members:\n   :show-inheritance:\n\nUCTB.model\\_unit.DCRNN\\_CELL module\n-----------------------------------\n\n.. automodule:: UCTB.model_unit.DCRNN_CELL\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model\\_unit.GraphModelLayers module\n----------------------------------------\n\n.. automodule:: UCTB.model_unit.GraphModelLayers\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model\\_unit.ST\\_RNN module\n-------------------------------\n\n.. automodule:: UCTB.model_unit.ST_RNN\n   :members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/_sources/UCTB.preprocess.rst.txt",
    "content": "UCTB.preprocess package\n=======================\n\n\nUCTB.preprocess.GraphGenerator module\n-----------------------------------\n\n.. automodule:: UCTB.preprocess.GraphGenerator\n   :members:\n   :show-inheritance:\n\nUCTB.preprocess.preprocessor module\n-----------------------------------\n\n.. automodule:: UCTB.preprocess.preprocessor\n   :members:\n   :show-inheritance:\n\nUCTB.preprocess.time\\_utils module\n----------------------------------\n\n.. automodule:: UCTB.preprocess.time_utils\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/_sources/UCTB.rst.txt",
    "content": "UCTB package\n============\n\nSubpackages\n-----------\n\n.. toctree::\n\n   UCTB.dataset\n   UCTB.evaluation\n   UCTB.model\n   UCTB.model_unit\n   UCTB.preprocess\n   UCTB.train\n   UCTB.utils\n\nModule contents\n---------------\n\n.. automodule:: UCTB\n   :members:\n   :undoc-members:\n   :show-inheritance:\n"
  },
  {
    "path": "docs/_sources/UCTB.train.rst.txt",
    "content": "UCTB.train package\n==================\n\nUCTB.train.EarlyStopping module\n-------------------------------\n\n.. automodule:: UCTB.train.EarlyStopping\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.train.MiniBatchTrain module\n--------------------------------\n\n.. automodule:: UCTB.train.MiniBatchTrain\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/_sources/UCTB.utils.rst.txt",
    "content": "UCTB.utils package\n==================\n\nUCTB.utils.multi\\_threads module\n--------------------------------\n\n.. automodule:: UCTB.utils.multi_threads\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n\n\n"
  },
  {
    "path": "docs/_sources/index.rst.txt",
    "content": ".. UCTB documentation master file, created by\n   sphinx-quickstart on Sun Jul 28 23:57:53 2019.\n   You can adapt this file completely to your liking, but it should at least\n   contain the root `toctree` directive.\n\nWelcome to UCTB's documentation!\n================================\n\n.. toctree::\n   :maxdepth: 2\n   :numbered:\n\n   md_file/introduction.md\n\n   md_file/installation.md\n\n   md_file/urban_dataset.md\n\n   md_file/predictive_tool.md\n\n   md_file/visualization_tool.md\n\n   APIReference.rst\n\n   md_file/all_results.md\n\n   md_file/uctb_group.md\n"
  },
  {
    "path": "docs/_sources/md_file/all_results.md.txt",
    "content": "#   Benchmark\n\n## Datasets\n\n| Application              |  Bike-sharing   |  Bike-sharing   |  Bike-sharing   |  Ride-sharing   |  Ride-sharing   |      Metro      |      Metro      |       EV        |  Traffic Speed  |  Traffic Speed  |\n| :----------------------- | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |\n| City                     | *New York City* |    *Chicago*    |      *DC*       |     *Xi'an*     |    *Chengdu*    |   *Chongqing*   |   *Shanghai*    |    *Beijing*    |    *METR-LA*    |   *PEMS-BAY*    |\n| Time span                | 2013.03-2017.09 | 2013.07-2017.09 | 2013.07-2017.09 | 2016.10-2016.11 | 2016.10-2016.11 | 2016.08-2017.07 | 2016.07-2016.09 | 2018.03-2018.05 | 2012.03-2012.06 | 2017.01-2017.07 |\n| Number of riding records |   49,100,694    |   13,130,969    |   13,763,675    |    5,922,961    |    8,439,537    |   409,277,117   |   333,149,034   |    1,272,961    |     34,272      |     52,128      |\n| Number of stations       |       820       |       585       |       532       |       256       |       256       |       113       |       288       |       629       |       207       |       325       |\n\nFollowing shows the map-visualization of stations in NYC, Chicago, DC, Xian and Chengdu.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_NYC.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_Chicago.jpg\" style=\"zoom:23%;height:800px;width:800px;\"/> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_DC.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/DiDi_Xian.jpg\" style=\"zoom:23%;height:800px;width:800px;\" />  <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/DiDi_Chengdu.jpg\" style=\"zoom:23%;height:800px;width:800px;\" />\n\n\n\nFollowing shows the map-visualization of stations in Chongqing, Shanghai and Beijing, METR-LA and PEMS-BAY.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Metro_Chongqing.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Metro_Shanghai.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/EV_Beijing.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/METR_LA.png\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/PEMS_BAY.png\" style=\"zoom:23%;height:800px;width:800px;\" />  \n\n## Results\n\nWe conducted experiments on the following datasets at the granularity of 15 minutes, 30 minutes, and 60 minutes respectively. More details and conclusions can be found in the this paper.  [IEEE Xplore](https://ieeexplore.ieee.org/document/9627543), [arXiv](https://arxiv.org/abs/2009.09379)\n\n### 15-minute prediction tasks\n\nThe best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction\n\n|                          |    NYC     |  Chicago   |     DC     |   Xi'an    |  Chengdu   |  Shanghai  | Chongqing  |  METR-LA   |  PEMS-BAY  |\n| :----------------------- | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: |\n| HM (TC)                  |   1.903    |   1.756    |   1.655    |   3.155    |   4.050    |   93.81    |   76.67    |   7.150    |   2.967    |\n| ARIMA (TC)               |   1.874    |   1.784    |   1.689    |   3.088    |   3.948    |   83.54    |   67.11    |   7.028    |   2.869    |\n| LSTM  (TC)               |   1.989    |   1.802    |   1.678    |   3.051    |   3.888    |   80.40    |   55.37    |   6.380    |   2.690    |\n| HM (TM)                  |   1.892    |   1.668    |   1.555    |   2.828    |   3.347    |   49.75    |   45.26    |   8.934    |   3.690    |\n| XGBoost (TM)             |   1.712    |   1.672    |   1.559    |   2.799    |   3.430    |   47.89    |   35.70    |   6.443    |   2.623    |\n| GBRT (TM)                |   1.708    |   1.667    |   1.552    |   2.775    |   3.363    |   44.55    |   33.29    |   6.371    |   2.645    |\n| TMeta-LSTM-GAL (TM)      |   1.818    |   1.623    |   1.540    |   2.917    |   3.286    |   45.88    |   33.34    |   6.156    |   2.544    |\n| DCRNN (TC+SP)            |   1.712    |   1.718    |   1.594    |   2.889    |   3.743    |   56.00    |   37.07    |   6.440    |   5.322    |\n| STGCN (TC+SP)            |   1.738    |   1.806    |   1.630    |   2.789    |   3.453    |   47.40    |   35.19    |   6.236    |   2.493    |\n| GMAN (TC+SP)             | **1.632*** | **1.529**  | **1.355*** |   2.769    |   3.520    |   49.21    |   36.66    |   6.214    |   3.484    |\n| Graph-WaveNet (TC+SP+SD) | **1.644**  | **1.460*** | **1.357**  |   2.764    |   3.442    |   47.84    |   35.04    | **5.270*** |   2.780    |\n| ST-ResNet (TM+SP)        |    ---     |    ---     |    ---     |   2.686    |   3.314    |    ---     |    ---     |    ---     |    ---     |\n| ST-MGCN (TM+SM)          |   1.687    |   1.646    |   1.545    |   2.714    |   3.293    |   46.54    | **32.72**  |   6.645    | **2.426*** |\n| AGCRN-CDW (TM+SD)        |   1.836    |   1.883    |   1.745    |   2.722    |   3.296    |   77.06    |   46.95    |   6.709    |   2.453    |\n| STMeta-GCL-GAL (TM+SM)   |   1.659    |   1.607    |   1.527    |   2.653    | **3.244**  | **41.67**  | **31.39*** | **5.644**  | **2.433**  |\n| STMeta-GCL-CON (TM+SM)   |   1.673    |   1.629    |   1.512    | **2.637*** | **3.241*** |   43.83    |   38.21    |   5.800    |   2.449    |\n| STMeta-DCG-GAL (TM+SM)   |   1.654    |   1.609    |   1.517    | **2.648**  |   3.254    | **40.94*** |   36.90    |   5.788    |   2.446    |\n\n### Results on 30-minute prediction tasks\n\nThe best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction\n\n|                          |    NYC     |  Chicago   |     DC     |   Xi'an    |  Chengdu   |  Shanghai  | Chongqing  |  Beijing   |  METR-LA   |  PEMS-BAY  |\n| :----------------------- | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: |\n| HM (TC)                  |   3.206    |   2.458    |   2.304    |   5.280    |   6.969    |   269.16   |   221.39   |   0.768    |   9.471    |   4.155    |\n| ARIMA (TC)               |   3.178    |   2.428    |   2.228    |   5.035    |   6.618    |   212.01   |   180.53   |   0.755    |   9.230    |   3.936    |\n| LSTM  (TC)               |   3.018    |   2.493    |   2.212    |   4.950    |   6.444    |   195.60   |   104.61   |   0.755    |   7.866    |   3.683    |\n| HM (TM)                  |   2.686    |   2.230    |   1.956    |   4.239    |   4.851    |   108.59   |   74.55    |   0.864    |   9.560    |   3.965    |\n| XGBoost (TM)             |   2.704    |   2.376    |   1.956    |   4.172    |   4.915    |   81.82    |   69.50    |   0.686    |   8.298    |   3.253    |\n| GBRT (TM)                |   2.682    |   2.355    |   1.928    |   4.135    |   4.873    |   83.94    |   72.99    |   0.689    |   8.269    |   3.370    |\n| TMeta-LSTM-GAL (TM)      |   2.511    | **2.133*** |   1.927    |   3.847    |   4.678    |   85.19    |   53.18    |   0.686    |   7.436    |   3.231    |\n| DCRNN (TC+SP)            |   2.618    |   2.246    |   2.118    |   4.529    |   6.258    |   116.15   |   65.72    |   0.757    |   8.562    |   6.198    |\n| STGCN (TC+SP)            |   2.841    |   2.482    |   2.067    |   3.992    |   5.051    |   91.29    |   58.34    |   0.694    |   7.871    |   3.136    |\n| GMAN (TC+SP)             |   2.792    |   2.336    | **1.836*** |   4.026    |   5.293    |   97.58    |   51.37    |   0.764    |   7.276    |   3.688    |\n| Graph-WaveNet (TC+SP+SD) |   2.666    |   2.158    |   1.874    |   3.986    |   5.097    |   92.88    |   52.52    |   0.719    | **6.809*** |   3.589    |\n| ST-ResNet (TM+SP)        |    ---     |    ---     |    ---     |   3.903    |   4.673    |    ---     |    ---     |    ---     |    ---     |    ---     |\n| ST-MGCN (TM+SM)          |   2.513    |   2.177    |   1.903    |   3.886    |   4.732    |   88.76    |   50.96    |   0.691    |   8.079    | **3.042**  |\n| AGCRN-CDW (TM+SD)        |   2.830    |   2.565    |   2.074    |   3.958    |   4.753    |   238.99   |   131.55   |   0.688    |   8.575    | **3.022*** |\n| STMeta-GCL-GAL (TM+SM)   | **2.410*** |   2.170    |   1.856    | **3.808**  |   4.650    | **75.36*** | **49.47**  | **0.670**  |   7.156    |   3.116    |\n| STMeta-GCL-CON (TM+SM)   | **2.411**  | **2.133*** |   1.859    | **3.772*** | **4.613*** |   80.69    |   50.01    | **0.667*** | **6.889*** |   3.204    |\n| STMeta-DCG-GAL (TM+SM)   | **2.411**  |   2.182    | **1.852**  |   3.833    | **4.635**  | **77.49**  | **48.96*** | **0.670**  |   7.184    |   3.187    |\n\n### Results on 60-minute prediction tasks\n\nThe best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction\n\n|                          |    NYC     |  Chicago   |     DC     |   Xi'an    |  Chengdu   |  Shanghai   | Chongqing  |  Beijing   |  METR-LA   |  PEMS-BAY  |\n| :----------------------- | :--------: | :--------: | :--------: | :--------: | :--------: | :---------: | :--------: | :--------: | :--------: | :--------: |\n| HM (TC)                  |   5.814    |   4.143    |   3.485    |   10.136   |   14.145   |   824.94    |   673.55   |   1.178    |   12.303   |   5.779    |\n| ARIMA (TC)               |   5.289    |   3.744    |   3.183    |   9.475    |   13.259   |   676.79    |   578.19   |   0.982    |   11.739   |   5.670    |\n| LSTM  (TC)               |   5.167    |   3.721    |   3.234    |   9.830    |   13.483   |   506.07    |   322.81   |   0.999    |   10.083   |   4.777    |\n| HM (TM)                  |   3.992    |   3.104    |   2.632    |   6.186    |   7.512    |   172.55    |   119.86   |   1.016    |   10.727   |   4.018    |\n| XGBoost (TM)             |   4.102    |   3.003    |   2.643    |   6.733    |   7.592    |   160.38    |   117.05   |   0.834    |   10.299   |   3.703    |\n| GBRT (TM)                |   4.039    |   2.984    |   2.611    |   6.446    |   7.511    |   154.29    |   113.92   |   0.828    |   10.013   |   3.704    |\n| TMeta-LSTM-GAL (TM)      |   3.739    |   2.840    |   2.557    | **5.843**  |   6.949    |   163.31    |   102.86   |   0.840    | **8.670*** |   3.616    |\n| DCRNN (TC+SP)            |   4.187    |   3.081    |   3.016    |   8.203    |   11.444   |   340.25    |   122.31   |   0.989    |   11.121   |   6.920    |\n| STGCN (TC+SP)            |   3.895    |   2.989    |   2.597    |   6.150    |   7.710    |   187.98    |   106.16   |   0.859    |   10.688   |   3.472    |\n| GMAN (TC+SP)             |   4.251    |   2.875    |   2.530    |   7.099    |   13.351   |   193.39    |   117.52   |   0.949    |   10.012   |   3.846    |\n| Graph-WaveNet (TC+SP+SD) |   3.863    |   2.812    | **2.403*** |   6.541    |   8.162    |   186.82    |   102.75   |   0.930    |   9.463    |   4.135    |\n| ST-ResNet (TM+SP)        |    ---     |    ---     |    ---     |   6.075    |   7.155    |     ---     |    ---     |    ---     |    ---     |    ---     |\n| ST-MGCN (TM+SM)          |   3.723    |   2.904    |   2.518    |   5.878    |   7.067    |   159.52    |   104.87   |   0.827    |   10.798   | **3.486**  |\n| AGCRN-CDW (TM+SD)        |   3.795    |   2.935    |   2.580    |   8.835    |   10.275   |   658.12    |   287.41   |   0.844    |   10.728   | **3.381*** |\n| STMeta-GCL-GAL (TM+SM)   | **3.518**  | **2.695**  |   2.405    |   5.871    | **6.858*** |   153.17    | **97.87**  |   0.831    | **8.834**  |   3.514    |\n| STMeta-GCL-CON (TM+SM)   | **3.507*** |   2.739    | **2.404**  | **5.829*** | **6.873**  | **149.05**  |   106.41   | **0.807**  |   9.147    |   3.552    |\n| STMeta-DCG-GAL (TM+SM)   |   3.521    | **2.652*** |   2.423    |   5.908    |   6.904    | **143.18*** | **94.78*** | **0.803*** |   8.993    |   3.500    |\n\n## Implement Details\n\n### Search Space\n\nWe use [nni](https://github.com/microsoft/nni) toolkit to search the best parameters of HM, XGBoost and GBRT model. Search space are following.\n\n|  Model  |                         Search Space                         |\n| :-----: | :----------------------------------------------------------: |\n|   HM    |               `CT: 0~6`, `PT: 0~7`, `TT: 0~4`                |\n|  ARIMA  |                ``CT:168``,`p:3`, `d:0`, `q:0`                |\n| XGBoost | `CT: 0~12`, `PT: 0~14`, `TT: 0~4`, `estimater: 10~200`, `depth: 2~10` |\n|  GBRT   | `CT: 0~12`, `PT: 0~14`, `TT: 0~4`, `estimater: 10~200`, `depth: 2~10` |\n\n### Bike-sharing\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |      NYC       |    Chicago     |       DC       |\n  | :--------: | :------------: | :------------: | :------------: |\n  |     HM     |    `3-1-2`     |    `5-0-4`     |    `3-7-4`     |\n  |  XGBoost   | `8-14-4-32-2`  | `11-13-4-28-2` | `4-14-4-27-2`  |\n  |    GBRT    | `7-13-4-144-1` | `7-15-4-101-2` | `8-11-5-101-2` |\n\n  | 30 minutes |      NYC       |    Chicago    |       DC        |\n  | :--------: | :------------: | :-----------: | :-------------: |\n  |     HM     |    `2-1-2`     |    `3-2-1`    |     `3-1-4`     |\n  |  XGBoost   | `12-8-1-36-3`  | `7-5-2-24-2`  | `12-13-4-27-2`  |\n  |    GBRT    | `12-10-0-72-4` | `9-13-2-91-2` | `13-15-5-140-1` |\n\n  | 60 minutes |      NYC       |    Chicago    |      DC       |\n  | :--------: | :------------: | :-----------: | :-----------: |\n  |     HM     |    `1-1-3`     |    `1-1-1`    |    `2-1-3`    |\n  |  XGBoost   | `13-7-0-103-3` | `11-8-0-35-4` | `11-9-5-28-3` |\n  |    GBRT    | `12-6-1-58-5`  | `11-8-1-92-5` | `11-8-5-54-3` |\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/bike_trial.py) Run Code & Setting.\n\n* [DCRNN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/bike_trial.py) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on  [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [bike_nyc.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_nyc.data.yml) , [bike_chicago.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_chicago.data.yml), [bike_dc.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_dc.data.yml)\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n            ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n            ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n            ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n            ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n            ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n            ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n  ```\n\n  * TMeta-LSTM-GAL\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p graph:Distance,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p graph:Distance,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p graph:Distance,MergeIndex:12')\n  ```\n\n  * STMeta-V1\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  ```\n\n  * STMeta-V2\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  ```\n\n  * STMeta-V3\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  ```\n\n### Ride-sharing\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |   **Xi'an**   |  **Chengdu**   |\n  | :--------: | :-----------: | :------------: |\n  |     HM     |    `5-0-4`    |    `2-7-4`     |\n  |  XGBoost   | `7-14-0-10-4` | `12-14-1-27-3` |\n  |    GBRT    | `11-2-2-45-3` | `13-15-5-39-3` |\n\n  | 30 minutes |  **Xi'an**   |  **Chengdu**   |\n  | :--------: | :----------: | :------------: |\n  |     HM     |   `2-0-2`    |    `1-7-4`     |\n  |  XGBoost   | `9-0-2-25-3` | `9-14-3-16-3`  |\n  |    GBRT    | `9-0-2-80-3` | `10-10-5-34-3` |\n\n  | 60 minutes |   **Xi'an**   |  **Chengdu**  |\n  | :--------: | :-----------: | :-----------: |\n  |     HM     |    `1-1-2`    |    `0-7-4`    |\n  |  XGBoost   | `12-0-2-10-5` | `9-6-2-14-3`  |\n  |    GBRT    | `9-0-2-50-2`  | `9-12-2-50-5` |\n\n* ST-ResNet\n\n  |                    ST-ResNet Search Space                    |\n  | :----------------------------------------------------------: |\n  | ``residual_units:2~6``,  `conv_filter:[32, 64, 128]`,  `kernal_size:3~5`, <br />`lr:[0.0001, 0.00002, 0.00004, 0.00008, 0.00001]`, `batch_size:[32, 64, 128, 256]` |\n\n  The best parameters found are following.\n\n  ```python\n  args = {\n    'dataset': 'DiDi',\n    'city': 'Chengdu',\n    'num_residual_unit': 4,\n    'conv_filters': 64,\n    'kernel_size': 3,\n    'lr': 1e-5,\n    'batch_size': 32\n  \n  ```\n\n  We can modify `city` parameter to `Chengdu` or `Xian` in [ST_ResNet.py]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_ResNet/ST_ResNet.py ) , and then run it.\n\n  ```bash\n   python ST_ResNet.py \n  ```\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/didi_trial.py) Run Code & Setting.\n\n* [DCRNN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/didi_trial.py ) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [didi_xian.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_xian.data.yml) , [didi_chengdu.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_chengdu.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    ```\n  \n  * TMeta-LSTM-GAL\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:12')\n    ```\n  \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    ```\n    \n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    ```\n  \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    ```\n    \n\n### Metro Passenger\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |  **Chongqing**  |  **Shanghai**  |\n  | :--------: | :-------------: | :------------: |\n  |     HM     |     `2-1-4`     |    `1-0-4`     |\n  |  XGBoost   |  `12-6-4-51-8`  | `11-10-4-31-7` |\n  |    GBRT    | `12-14-1-182-7` | `12-7-1-148-5` |\n\n  | 30 minutes | **Chongqing**  |  **Shanghai**  |\n  | :--------: | :------------: | :------------: |\n  |     HM     |    `1-0-4`     |    `1-1-3`     |\n  |  XGBoost   | `11-5-0-45-8`  | `12-6-1-206-3` |\n  |    GBRT    | `10-3-0-107-8` |  `7-4-1-58-7`  |\n\n  | 60 minutes |  **Chongqing**   | **Shanghai** |\n  | :--------: | :--------------: | :----------: |\n  |     HM     |     `0-1-4`      |   `0-0-4`    |\n  |  XGBoost   |  `9-14-2-200-5`  | `3-7-0-50-5` |\n  |    GBRT    | `12-10-4-200-5 ` | `9-5-1-66-6` |\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metro_trial.py ) Run Code & Setting.\n\n* [DCRNN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metro_trial.py) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [metro_chongqing.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_chongqing.data.yml) , [metro_shanghai.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_shanghai.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM \n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    ```\n    \n  * TMeta-LSTM-GAL\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:12')\n    ```\n  \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    ```\n  \n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    ```\n    \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n            '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    ```\n    \n\n### Electric Vehicle\n\n* HM & XGBoost & GBRT\n\n  | Beijing |  30 minutes   |   60 minutes    |\n  | :-----: | :-----------: | :-------------: |\n  |   HM    |    `2-0-0`    |     `2-0-2`     |\n  | XGBoost | `6-6-1-19-2`  |  `12-7-0-20-2`  |\n  |  GBRT   | `13-3-2-47-3` | `12-10-0-100-2` |\n\n* [ST_MGCN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/cs_trial.py ) Run Code & Setting.\n\n* [DCRNN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/cs_trial.py ) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [chargestation_beijing.data.yml]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/chargestation_beijing.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM \n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:2')\n    ```\n  \n  * TMeta-LSTM-GAL\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:2')\n    ```\n  \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n            ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n    ```\n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n            ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n    ```\n  \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n    ```\n\n### Traffic Speed\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |  **METR-LA**  | **PEMS-BAY**  |\n  | :--------: | :-----------: | :-----------: |\n  |     HM     |    `2-0-4`    |    `1-0-1`    |\n  |  XGBoost   | `11-1-2-25-3` | `12-4-2-21-4` |\n  |    GBRT    | `11-8-2-29-4` | `10-6-1-65-6` |\n\n  | 30 minutes |  **METR-LA**  |  **PEMS-BAY**  |\n  | :--------: | :-----------: | :------------: |\n  |     HM     |    `2-0-4`    |    `1-0-1`     |\n  |  XGBoost   | `6-6-0-25-3`  | `12-13-2-27-3` |\n  |    GBRT    | `10-0-0-27-3` | `12-6-2-90-7`  |\n\n  | 60 minutes |  **METR-LA**  | **PEMS-BAY**  |\n  | :--------: | :-----------: | :-----------: |\n  |     HM     |    `2-1-4`    |    `1-1-4`    |\n  |  XGBoost   | `2-2-0-25-3`  | `12-6-2-19-3` |\n  |    GBRT    | `4-5-1-19-4`  | `12-7-2-59-5` |\n\n* [METR-LA](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metr_trial.py)  and [PEMS-BAY](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/pems_trial.py)  ST_MGCN Run Code & Setting.\n\n* [METR-LA](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metr_trial.py) and [PEMS-BAY](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/pems_trial.py) DCRNN Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [metr_la.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metr_la.data.yml) , [pems_bay.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/pems_bay.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM \n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    ```\n\n  * TMeta-LSTM-GAL\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:12')\n    ```\n\n  * STMeta-V1\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    ```\n\n  * STMeta-V2\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    ```\n\n  * STMeta-V3\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    ```\n\n"
  },
  {
    "path": "docs/_sources/md_file/all_results_setting.md.txt",
    "content": "# Experiment Setting on different datasets\n\n## STMeta Version\n\n| Version Name | Temporal Feature Process | Temporal Merge Method | Multi-Graph Merge Method |\n| :----------: | :----------------------: | :-------------------: | :----------------------: |\n|  STMeta-V1   |          GCLSTM          |          GAL          |           GAL            |\n|  STMeta-V2   |          GCLSTM          |     Concat&Dense      |           GAL            |\n|  STMeta-V3   |          DCRNN           |          GAL          |           GAL            |\n\nBy default, we use `STMeta-V1` to run LSTM and single graph model tests.\n\n## Search Space\n\n|  Model  |                         Search Space                         |\n| :-----: | :----------------------------------------------------------: |\n|   HM    |               `CT: 0~6`, `PT: 0~7`, `TT: 0~4`                |\n|  ARIMA  |                ``CT:168``,`p:3`, `d:0`, `q:0`                |\n| XGBoost | `CT: 0~12`, `PT: 0~14`, `TT: 0~4`, `estimater: 10~200`, `depth: 2~10` |\n|  GBRT   | `CT: 0~12`, `PT: 0~14`, `TT: 0~4`, `estimater: 10~200`, `depth: 2~10` |\n\n## Results on Bike\n\n### Dataset Statistics\n\n|        Attributes        | **New York City** |   **Chicago**   |     **DC**      |\n| :----------------------: | :---------------: | :-------------: | :-------------: |\n|        Time span         |  2013.03-2017.09  | 2013.07-2017.09 | 2013.07-2017.09 |\n| Number of riding records |    49,100,694     |   13,130,969    |   13,763,675    |\n|    Number of stations    |        820        |       585       |       532       |\n\n### Experiment Setting\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/bike_trial.py) Run Code & Setting.\n\n* [DCRNN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/bike_trial.py) Run Code & Setting.\n\n* LSTM (C) & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  All four models can be run by specifying data files and model files on  [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [bike_nyc.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_nyc.data.yml) , [bike_chicago.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_chicago.data.yml), [bike_dc.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_dc.data.yml).\n\n  * LSTM (C)\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n    ```\n    \n    Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml).\n    \n  * STMeta-V1 \n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    ```\n  \n    Model Files: [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).\n  \n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    ```\n    \n    \n    Model Files: [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml).\n    \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    ```\n  \n      Model Files: [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n### Experiment Results\n\n|                 |        **NYC**         |       **Chicago**       |         **DC**          |\n| :-------------: | :--------------------: | :---------------------: | :---------------------: |\n|       HM        |    3.99224 `1-1-3`     |     2.97693 `1-1-2`     |     2.63165 `2-1-3`     |\n|    ARIMA(C)     |  5.60928 `168-3-0-0`   |   3.83584 `168-3-0-0`   |   3.60450 `168-3-0-0`   |\n|     XGBoost     | 4.12407 `12-10-0-20-5` |  2.92569 `9-7-0-20-5`   | 2.65671 `12-14-2-20-5`  |\n|      GBRT       | 3.99907 `12-7-4-100-5` | 2.84257 `12-14-2-100-5` | 2.61768 `12-14-2-100-5` |\n| ST_MGCN (G/DCI) |        3.72380         |         2.88300         |         2.48560         |\n|  DCRNN(G/D C)   |        4.18666         |         3.27759         |         3.08616         |\n|    LSTM (C)     |        4.55677         |         3.37004         |         2.91518         |\n|    STMeta-V1    |        3.50475         |       **2.65511**       |         2.42582         |\n|    STMeta-V2    |      **3.43870**       |         2.66379         |         2.41111         |\n|    STMeta-V3    |        3.47834         |         2.66180         |       **2.38844**       |\n\n## Results on DiDi\n\n### Dataset Statistics\n\n|        Attributes        |    **Xi'an**    |   **Chengdu**   |\n| :----------------------: | :-------------: | :-------------: |\n|        Time span         | 2016.10-2016.11 | 2016.10-2016.11 |\n| Number of riding records |    5,922,961    |    8,439,537    |\n|    Number of stations    |       256       |       256       |\n\n### Experiment Setting\n\n* ST-ResNet\n\n  |                    ST-ResNet Search Space                    |\n  | :----------------------------------------------------------: |\n  | ``residual_units:2~6``,  `conv_filter:[32, 64, 128]`,  `kernal_size:3~5`, <br />`lr:[0.0001, 0.00002, 0.00004, 0.00008, 0.00001]`, `batch_size:[32, 64, 128, 256]` |\n\n  The best parameters found are following.\n\n  ```python\n  args = {\n    'dataset': 'DiDi',\n    'city': 'Chengdu',\n    'num_residual_unit': 4,\n    'conv_filters': 64,\n    'kernel_size': 3,\n    'lr': 1e-5,\n    'batch_size': 32\n  }\n  ```\n\n  We can modify `city` parameter to `Chengdu` or `Xian` in [ST_ResNet.py]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_ResNet/ST_ResNet.py ) , and then run it.\n\n  ```bash\n   python ST_ResNet.py \n  ```\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/didi_trial.py) Run Code & Setting.\n\n* [DCRNN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/didi_trial.py ) Run Code & Setting.\n\n* LSTM (C) & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  All four models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [didi_xian.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_xian.data.yml) , [didi_chengdu.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_chengdu.data.yml).\n\n  * LSTM (C)\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n    ```\n\n    Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml).\n\n  * STMeta-V1\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    \n    ```\n  \n    Model Files: [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).\n  \n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n                '-p graph:Distance-Correlation-Interaction')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n                '-p graph:Distance-Correlation-Interaction')   \n    ```\n  \n    Model Files: [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml).\n  \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction')\n    ```\n  \n    Model Files: [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n### Experiment Results\n\n|                   |       **Xi’an**        |      **Chengdu**      |\n| :---------------: | :--------------------: | :-------------------: |\n|        HM         |    6.18623 `1-1-2`     |    7.35477 `0-1-4`    |\n|     ARIMA(C)      |  9.47478 `168-3-0-0`   | 12.52656 `168-3-0-0`  |\n|      XGBoost      | 6.73346 `12-0-2-10-5 ` | 7.73836`9-14-4-20-2`  |\n|       GBRT        | 6.44639 `9-0-2-50-2 `  | 7.58831 `12-7-2-50-5` |\n|     ST-ResNet     |        6.08476         |        7.14638        |\n|  ST_MGCN (G/DCI)  |        5.87456         |      **7.03217**      |\n|   DCRNN(G/D C)    |        8.20254         |       11.50550        |\n|     LSTM (C)      |        7.39970         |       10.11386        |\n| STMeta-V1 (G/DCI) |        5.89154         |        7.06246        |\n| STMeta-V2(G/DCI)  |      **5.75596**       |        7.09710        |\n| STMeta-V3(G/DCI)  |        5.95507         |        7.04358        |\n\n## Results on Metro\n\n### Dataset Statistics\n\n|        Attributes        |  **Chongqing**  |  **Shanghai**   |\n| :----------------------: | :-------------: | :-------------: |\n|        Time span         | 2016.08-2017.07 | 2016.07-2016.09 |\n| Number of riding records |   409,277,117   |   333,149,034   |\n|    Number of stations    |       113       |       288       |\n\n### Experiment Setting\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metro_trial.py ) Run Code & Setting.\n\n* [DCRNN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metro_trial.py) Run Code & Setting.\n\n* LSTM (C) & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  All four models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [metro_chongqing.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_chongqing.data.yml) , [metro_shanghai.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_shanghai.data.yml).\n  \n  * LSTM (C) \n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n                ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n                ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n    ```\n  \n    Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml).\n  \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n                '-p graph:Distance-Correlation-Line')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n                  '-p graph:Distance-Correlation-Line')\n    ```\n  \n    Model Files: [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).\n  \n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n            '-p graph:Distance-Correlation-Line')\n    ```\n  \n  Model Files: [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml).\n  \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n                '-p graph:Distance-Correlation-Line')\n    ```\n  \n\n  Model Files: [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n### Experiment Results\n\n|                   |       **Chongqing**       |       **Shanghai**        |\n| :---------------: | :-----------------------: | :-----------------------: |\n|        HM         |     120.30723 `0-1-4`     |     197.97092 `0-1-4`     |\n|     ARIMA(C)      |   578.18563 `168-3-0-0`   |   792.1597 `168-3-0-0`    |\n|      XGBoost      | 117.05069 `9-14-2-200-5`  |   185.00447`3-7-0-50-5`   |\n|       GBRT        | 113.92276 1`2-10-4-200-5` | 186.74502 `12-10-0-100-2` |\n|  ST_MGCN (G/DCI)  |         118.86668         |         181.55171         |\n|   DCRNN(G/D C)    |         122.31121         |         326.97357         |\n|     LSTM (C)      |        196.175732         |         368.8468          |\n| STMeta-V1 (G/DCI) |       **92.74990**        |       **151.11746**       |\n| STMeta-V2(G/DCI)  |         98.86152          |         158.21953         |\n| STMeta-V3(G/DCI)  |         101.7806          |         156.58867         |\n\nThe period and trend features are more obvious in Metro dataset, so the performance is poor if only use closeness feature.\n\n## Results on Charge-Station\n\n### Dataset Statistics\n\n|        Attributes        |   **Beijing**   |\n| :----------------------: | :-------------: |\n|        Time span         | 2018.03-2018.08 |\n| Number of riding records |    1,272,961    |\n|    Number of stations    |       629       |\n\n### Experiment Setting\n\n* [ST_MGCN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/cs_trial.py ) Run Code & Setting.\n\n* [DCRNN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/cs_trial.py ) Run Code & Setting.\n\n* LSTM (C) & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  All four models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [chargestation_beijing.data.yml]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/chargestation_beijing.data.yml).\n\n  * LSTM (C) \n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC')\n    \n    ```\n    \n    \n    Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml).\n    \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation')\n    \n    ```\n  \n  \n    Model Files: [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).\n  \n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n                ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation')\n    \n    ```\n  \n  \n    Model Files: [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml).\n  \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n                ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation')\n    ```\n  \n  \n    Model Files: [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n### Experiment Results\n\n|                  |       **Beijing**       |\n| :--------------: | :---------------------: |\n|        HM        |     1.01610 `2-0-2`     |\n|     ARIMA(C)     |   0.98236 `168-3-0-0`   |\n|     XGBoost      |  0.83381 `12-7-0-20-2`  |\n|       GBRT       | 0.82814 `12-10-0-100-2` |\n|  ST_MGCN (G/DC)  |         0.82714         |\n|   DCRNN(G/D C)   |         0.98871         |\n|     LSTM (C)     |         1.58560         |\n| STMeta-V1 (G/DC) |      **0.815518**       |\n| STMeta-V2(G/DC)  |         0.82144         |\n| STMeta-V3(G/DC)  |       **0.81541**       |\n\n"
  },
  {
    "path": "docs/_sources/md_file/index.md.txt",
    "content": "# [Urban Computing ToolBox](https://github.com/Di-Chai/UCTB)\n\n## Introduction\n\n**Urban Computing Tool Box** is a package providing **spatial-temporal prediction models** for various urban computing tasks, such as traffic prediction, crowd flow prediction, ridesharing demand prediction, etc. It contains both conventional models and state-of-art models.\n\nCurrently the package supported the following models: (This tool box is constructed based on some open-source repos. We appreciate these awesome implements.  [See more details](https://uctb.github.io/UCTB/md_file/static/current_supported_models.html))\n\n- ARIMA\n- HM\n- HMM\n- XGBoost\n- DeepST [[SIGSPATIAL 2016]](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf)\n- ST-ResNet [[AAAI 2017]](https://arxiv.org/pdf/1610.00081.pdf)\n- DCRNN [[ICLR 2018]](https://arxiv.org/pdf/1707.01926.pdf)\n- GeoMAN [[IJCAI 2018]](https://www.ijcai.org/proceedings/2018/0476.pdf)\n- STGCN [[IJCAI 2018]](https://www.ijcai.org/proceedings/2018/0505.pdf)\n- GraphWaveNet [[IJCAI 2019]](https://www.ijcai.org/proceedings/2019/0264.pdf)\n- ASTGCN [[AAAI 2019]](https://ojs.aaai.org/index.php/AAAI/article/view/3881)\n- ST-MGCN [[AAAI 2019]](https://ojs.aaai.org/index.php/AAAI/article/view/4247)\n- GMAN [[AAAI 2020]](https://ojs.aaai.org/index.php/AAAI/article/view/5477/5333)\n- STSGCN [[AAAI 2020]](https://ojs.aaai.org/index.php/AAAI/article/view/5438)\n- AGCRN [[NeurIPS 2020]](https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf)\n- STMeta  [[TKDE 2021]](https://arxiv.org/abs/2009.09379)\n\nUCTB is a flexible and open package. You can use the data we provided or use your own data, the data structure is well stated in the tutorial chapter. You can build your own model based on model-units we provided and use the model-training class to train the model.\n\n## Installation\n\n### Install UCTB\n\n##### Step 1: Install TensorFlow\n\nYou can skip to step 2 if you already installed tensorflow.\n\nYou can refer to this page <https://www.tensorflow.org/install> to install tensorflow, if you have a Nvidia GPU installed on you computer, we highly recommend you to install GPU version of tensorflow.\n\n##### Step 2: Install UCTB\n\n```bash\npip install --upgrade UCTB\n```\n\nThe following required package will be installed or upgraded with UCTB:\n\n```bash\n'hmmlearn',\n'keras',\n'GPUtil',\n'numpy',\n'pandas',\n'python-dateutil',\n'scikit-learn',\n'scipy',\n'statsmodels',\n'wget',\n'xgboost',\n'nni',\n'chinesecalendar',\n'PyYAML'\n```\n\n### UCTB Docker\n\nYou can also  use UCTB by docker. First pull uctb docker from docker hub.\n\n```bash\ndocker pull dichai/uctb:v0.2.0\n```\n\nAnd  you then can run it.\n\n```bash\ndocker run  --runtime=nvidia  -it -d dichai/uctb:v0.2.0 /bin/bash\n```\n\n## Quick start\n\n- ##### Quick start with STMeta\n\n```python\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\n\n# Config data loader\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', graph='Correlation',\n                                closeness_len=6, period_len=7, trend_len=4, normalize=True)\n\n# Init model object\nSTMeta_Obj = STMeta(closeness_len=data_loader.closeness_len,\n                                 period_len=data_loader.period_len,\n                                 trend_len=data_loader.trend_len,\n                                 num_node=data_loader.station_number,\n                                 num_graph=data_loader.LM.shape[0])\n\n# Build tf-graph\nSTMeta_Obj.build()\n# Training\nSTMeta_Obj.fit(closeness_feature=data_loader.train_closeness,\n                      period_feature=data_loader.train_period,\n                      trend_feature=data_loader.train_trend,\n                      laplace_matrix=data_loader.LM,\n                      target=data_loader.train_y,\n                      sequence_length=data_loader.train_sequence_len)\n\n# Predict\nprediction = STMeta_Obj.predict(closeness_feature=data_loader.test_closeness,\n                                       period_feature=data_loader.test_period,\n                                       trend_feature=data_loader.test_trend,\n                                       laplace_matrix=data_loader.LM,\n                                       target=data_loader.test_y,\n                                       output_names=['prediction'],\n                                       sequence_length=data_loader.test_sequence_len)\n\n# Evaluate\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.min_max_denormal(prediction['prediction']),\n                                 target=data_loader.normalizer.min_max_denormal(data_loader.test_y)))\n```\n\n- [Quick start with other models](./static/quick_start.html)\n\n## Tutorial\n\n- Compare different version of STMeta\n\n- ##### [Use datasets from UCTB](./static/tutorial.html)\n\n- ##### [Build your own datasets](./static/tutorial.html)\n\n- ##### Use build-in models from UCTB\n\n\n- ##### Build your own model using UCTB\n\n\n## API Reference\n\n- ##### Model Class\n\n\n- ##### ModelUnit Class\n\n\n- ##### Evaluation Class\n\n\n- ##### Training Class\n\n\n## Full examples\n\n- ##### [Experiments on bike traffic-flow prediction](./static/experiment_on_bike.html)\n\n- ##### [Experiments on metro traffic-flow prediction](./static/experiment_on_metro.html)\n\n- Experiments on charge station demand prediction\n\n## Contribute to UCTB (Delay)\n\n- ##### Contribute Data\n- ##### Contribute Models\n- ##### Contribute Model-Units\n"
  },
  {
    "path": "docs/_sources/md_file/installation.md.txt",
    "content": "## Installation\n\nUCTB is based on several well-known deep learning frameworks, including **PyTorch**, **TensorFlow**, and **MXNet**. If you have an Nvidia GPU installed on your computer, we highly recommend you install the GPU version of these frameworks.\n\nUCTB toolbox may not work successfully with the upgrade of some packages. We thus encourage you to use the specific version of packages to avoid unseen errors. ***To avoid potential conflict, we highly recommend you install UCTB vis Anaconda.***\n\n### Install via Anaconda\n\n**Step 1: Install Anaconda**\n\nYou can skip to step 2 if you already installed Anaconda.\n\nTo install Anaconda, please refer to this page <https://www.anaconda.com/download>.\n\n\n\n**Step 2: create UCTB environment**\n\nCreate the UCTB environment by the following command. You may need the [environment.yaml](https://github.com/uctb/UCTB/blob/master/environment.yaml) file.\n\n```bash\nconda env create -f environment.yaml\n```\n\nThen activate the UCTB environment and start to use it. 🎉🎉🎉\n\n```bash\nconda activate UCTB\n```\n\n\n\n### Check for Success\n\nIf you  successfully install UCTB, you may get the following output after importing UCTB. \n\n```\n(UCTB) XXX:~$ python\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n>>> import UCTB\nUsing TensorFlow backend.\n>>> \n```\n\n### High version GPU Framework support\n\n**Existing Problems**\n\nDue to changes in the design architecture of high-version GPUs, low-version CUDA is not compatible with high-version GPUs. As a result, Tensorflow 1.x is only compatible with low-version CUDA, leading to runtime failures on machines equipped with high-version GPUs. https://stackoverflow.com/questions/50622525/which-tensorflow-and-cuda-version-combinations-are-compatible \n\n**Solution**\n\nThanks to the [Nvidia TensorFlow](https://github.com/NVIDIA/tensorflow) project, which was created to support newer hardware and improve libraries for NVIDIA GPU users using TensorFlow 1.x, we can now install UCTB on machines with newer GPUs. You can follow the installation tutorial below to start enjoying UCTB.\n\n**Clone the project**\n\n```sh\n>>> git clone git@github.com:uctb/UCTB.git\n>>> cd UCTB\n```\n\n**Create Anaconda Environment**\n\n```sh\n>>> conda create -n UCTB python=3.8\n>>> conda activate UCTB\n```\n\n**Install Nvidia Tensorflow**\n\n```sh\n>>> pip install --user nvidia-pyindex\n>>> pip install --user nvidia-tensorflow[horovod]\n```\n\n**Install UCTB from Source**\n\n```sh\n>>> python build_install.py\n```\n\n\n\n### Q & A\n\n**Q: I fail to install PyTorch, TensorFlow, and MXNet, what is the version number of them?**\n\nA: We recommend you install PyTorch==1.1.0, TensorFlow==1.13.1, and MXNet==1.5.0 with cuda version 10.0. We here give the installation command:\n\n```bash\n# Install PyTorch\nconda install pytorch==1.1.0 torchvision==0.3.0 cudatoolkit=10.0 -c pytorch\n\n# Install TensorFlow\nconda install tensorflow-gpu==1.13.1\n\n# Install MXNet\npip install mxnet-cu100==1.5.0\n```\n\n\n\n**Q:  I'm using Windows OS, and my Anaconda reports that it cannot find the PyTorch 1.1.0 packages. How to install it?**\n\nA: You could install it by the following command.\n\n```bash\npip install torch==1.1.0 torchvision==0.3.0 -f https://download.pytorch.org/whl/cu100/torch_stable.html\n```\n\n\n\n**Q:  I fail to install UCTB via pip. How to install it ?**\n\nA: This situation may occur when your OS is Windows. You could install UCTB by its source code. First download UCTB's source code and your folder may look like this:\n\n```bash\nXXX/UCTB-master# ls\nbuild_install.py  dist  environment.yaml  __init__.py  QuickStarts  setup.py\nbuild.py          docs  Experiments       LICENSE      README.md    UCTB\n```\n\nthen build and install UCTB by the following command:\n\n```bash\npython build_install.py\n```\n\n<u>[Back To HomePage](../index.html)</u>"
  },
  {
    "path": "docs/_sources/md_file/introduction.md.txt",
    "content": "## Introduction\n\n**Urban Computing Tool Box** is a package providing [**urban datasets**](https://github.com/uctb/Urban-Dataset), [**spatial-temporal prediction models**](https://github.com/uctb/UCTB), and [**visualization tools**](https://github.com/uctb/visualization-tool-UCTB) for various urban computing tasks, such as traffic prediction, crowd flow prediction, ridesharing demand prediction, etc. \n\nUCTB is a flexible and open package. You can use the data we provided or use your data, and the data structure is well stated in the [**tutorial section**](https://uctb.github.io/UCTB/md_file/tutorial.html). \n\n### Urban Datasts\n\nUCTB also releases [a public dataset repository](https://github.com/uctb/Urban-Dataset) including the following applications:\n\n| **Application**  |        **City**        |     **Time Range**     | **Temporal Granularity** |                                                      **Dataset Link**                                                       |\n|:----------------:|:----------------------:|:----------------------:|:------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|\n|   Bike-sharing   |          NYC           | 2013.07.01-2017.09.30  |        5 minutes         |            [66.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip)             | \n|   Bike-sharing   |        Chicago         | 2013.07.01-2017.09.30  |        5 minutes         |          [30.2M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip)           | \n|   Bike-sharing   |           DC           | 2013.07.01-2017.09.30  |        5 minutes         |             [31.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip)             | \n| Pedestrian Count |       Melbourne        | 2021.01.01-2022.11.01  |        60 minutes        | [1.18M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip) |\n|  Vehicle Speed   |           LA           | 2012.03.01-2012.06.28  |        5 minutes         |            [11.8M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip)             |\n|  Vehicle Speed   |          BAY           | 2017.01.01-2017.07.01  |        5 minutes         |            [27.9M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip)            |\n|   Taxi Demand    |        Chicago         | 2013.01.01-2018.01.01  |        15 minutes        |          [6.1M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|       Bus        |          NYC           | 2022.02.01-2024.01.13  |         60 mins          |             [4.89M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip)             |\n|      Metro       |          NYC           | 2022.02.01-2023.12.21  |         60 mins          |           [11.3M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip)           |\n|   Traffic Flow   |         Luzern         | 2015.01.01-2016.01.01  |          3 mins          |            [21M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Flow/3_minutes/Flow_Luzern.zip)            |\n|   Ride-sharing   |  Chicago (community)   | 2013.01.01-2018.01.01  |         15 mins          |          [6.06](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|   Ride-sharing   | Chicago (census tract) | 2013.01.01-2018.01.01  |         15 mins          |    [10M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip)     |\n|   Ride-sharing   |          NYC           | 2009.01.01-2023.06.01  |          5 mins          |    \n\nWe provide [detailed documents](https://github.com/uctb/Urban-Dataset/blob/main/Tutorial/tutorial.ipynb) about how to build and how to use these datasets.\n\n### Predictive Tool\n\nCurrently, the package supports the following models: (This toolbox is constructed based on some open-source repos. We appreciate these awesome implements. [See more details](https://uctb.github.io/UCTB/md_file/static/current_supported_models.html)).\n\n| Model Name                                                   | Input Data Format | Spatial Modeling Technique | Graph Type                                                   | Temporal Modeling Technique | Temporal Knowledge     | Module                      |\n| ------------------------------------------------------------ | ----------------- | -------------------------- | ------------------------------------------------------------ | --------------------------- | ---------------------- | --------------------------- |\n| ARIMA                                                        | Both              | N/A                        | N/A                                                          | SARIMA                      | Closeness              | ``UCTB.model.ARIMA``        |\n| HM                                                           | Both              | N/A                        | N/A                                                          | N/A                         | Closeness              | ``UCTB.model.HM``           |\n| HMM                                                          | Both              | N/A                        | N/A                                                          | HMM                         | Closeness              | ``UCTB.model.HMM``          |\n| XGBoost                                                      | Both              | N/A                        | N/A                                                          | XGBoost                     | Closeness              | ``UCTB.model.XGBoost``      |\n| DeepST [[SIGSPATIAL 2016]](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf) | Grid              | CNN                        | N/A                                                          | CNN                         | Closeness,Period,Trend | ``UCTB.model.DeepST``       |\n| ST-ResNet [[AAAI 2017]](https://arxiv.org/pdf/1610.00081.pdf) | Grid              | CNN                        | N/A                                                          | CNN                         | Closeness,Period,Trend | ``UCTB.model.ST_ResNet``    |\n| DCRNN  [[ICLR 2018]](https://arxiv.org/pdf/1707.01926.pdf)   | Node              | GNN                        | **Prior**(Sensor Network)                                    | RNN                         | Closeness              | ``UCTB.model.DCRNN``        |\n| GeoMAN  [[IJCAI 2018]](https://www.ijcai.org/proceedings/2018/0476.pdf) | Node              | Attention                  | **Prior**(Sensor Networks)                                   | Attention+LSTM              | Closeness              | ``UCTB.model.GeoMAN``       |\n| STGCN  [[IJCAI 2018]](https://www.ijcai.org/proceedings/2018/0505.pdf) | Node              | GNN                        | **Prior**(Traffic Network)                                   | Gated CNN                   | Closeness              | ``UCTB.model.STGCN``        |\n| GraphWaveNet [[IJCAI 2019]](https://www.ijcai.org/proceedings/2019/0264.pdf) | Node              | GNN                        | **Adaptive**                                                 | TCN                         | Closeness              | ``UCTB.model.GraphWaveNet`` |\n| ASTGCN  [[AAAI 2019]](https://ojs.aaai.org/index.php/AAAI/article/view/3881) | Node              | GNN+Attention              | **Prior**(Traffic Network)                                   | Attention                   | Closeness,Period,Trend | ``UCTB.model.ASTGCN``       |\n| ST-MGCN   [[AAAI 2019]](https://ojs.aaai.org/index.php/AAAI/article/view/4247) | Node              | GNN                        | **Prior**(Neighborhood,Functional similarity,Transportation connectivity) | CGRNN                       | Closeness              | ``UCTB.model.ST_MGCN``      |\n| GMAN  [[AAAI 2020]](https://ojs.aaai.org/index.php/AAAI/article/view/5477/5333) | Node              | Attention                  | **Prior**(Road Network)                                      | Attention                   | Closeness              | ``UCTB.model.GMAN``         |\n| STSGCN  [[AAAI 2020]](https://ojs.aaai.org/index.php/AAAI/article/view/5438) | Node              | GNN+Attention              | **Prior**(Spatial Network)                                   | Attention                   | Closeness              | ``UCTB.model.STSGCN``       |\n| AGCRN [[NeurIPS 2020]](https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf) | Node              | GNN                        | **Adaptive**                                                 | RNN                         | Closeness              | ``UCTB.model.AGCRN``        |\n| STMeta [[TKDE 2021]](https://arxiv.org/abs/2009.09379)       | Node              | GNN                        | **Prior**(Proximity,Functionality,Interaction/Same-line)     | LSTM/RNN                    | Closeness,Period,Trend | ``UCTB.model.STMeta``       |\n\n### Visualization Tool\n\nThe Visualization tool integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis.\n\nWelcome to visit the [website](http://39.107.116.221/) for a trial! \n\n<u>[Back To HomePage](../index.html)</u>\n"
  },
  {
    "path": "docs/_sources/md_file/predictive_tool.md.txt",
    "content": "# Predictive Tool\n\n## Currently Supported Models\n\n### AGCRN\n\nAGCRN (Adaptive Graph Convolutional Recurrent Network) is a deep nerual network for traffic prediction consisting of two adaptive module and recurrent networks.\n\n- Reference Paper:\n  - [Bai, L., Yao, L., Li, C., Wang, X., & Wang, C. (2020). Adaptive graph convolutional recurrent network for traffic forecasting.](https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf)\n- Reference Implementation:\n  - [Github repository (LeiBAI)](https://github.com/LeiBAI/AGCRN)\n\n###  ARIMA\n\nARIMA (Autoregressive Integrated Moving Average) is a widely used classical statistical model on time series prediction.\n\n- Reference Paper:\n\n  + [Williams, B. M., & Hoel, L. A. (2003). Modeling and forecasting vehicular traffic flow as a seasonal ARIMA process: Theoretical basis and empirical results](https://www3.nd.edu/~busiforc/handouts/ARIMA%20Engineering%20Article.pdf)\n- Reference Package: `pandas`, `statsmodels`\n\n### ASTGCN \n\nASTGCN (Attenion Based Spatial-temporal Graph Convolutional Networks) is a deep neural network for traffic flow forecasting. It models temporal-dependencies from three perspectives using attetion mechanism. And it models spatial-dependencies employing graph convolutions.\n\n- Reference Paper:\n  - [Guo, S., Lin, Y., Feng, N., Song, C., & Wan, H. (2019, July). Attention based spatial-temporal graph convolutional networks for traffic flow forecasting.](https://ojs.aaai.org/index.php/AAAI/article/view/3881)\n- Reference Implementation:\n  - [Github repository (guoshnBJTU)](https://github.com/guoshnBJTU/ASTGCN-r-pytorch)\n\n###  DCRNN\n\nDCRNN (Diffusion Convolutional Recurrent Neural Network) is a deep learning framework for traffic forecasting that incorporates both spatial and temporal dependency in the traffic flow. It captures the spatial dependency using bidirectional random walks on the graph, and the temporal dependency using the encoder-decoder architecture with scheduled sampling.\n\n- Reference Paper:\n\n  + [Li, Y., Yu, R., Shahabi, C., & Liu, Y. (2017). Diffusion convolutional recurrent neural network: Data-driven traffic forecasting](https://arxiv.org/abs/1707.01926)\n- Reference Implementation: \n  + [A TensorFlow implementation of Diffusion Convolutional Recurrent Neural Network (liyaguang)](https://github.com/liyaguang/DCRNN)\n\n###  DeepST\n\nDeepST (Deep learning-based prediction model for Spatial-Temporal data) is composed of three components: 1) temporal dependent instances: describing temporal closeness, period and seasonal trend; 2) convolutional neural networks: capturing near and far spatial dependencies; 3) early and late fusions: fusing similar and different domains' data.\n\n- Reference Paper:\n\n  + [Zhang, J., Zheng, Y., Qi, D., Li, R., & Yi, X. (2016, October). DNN-based prediction model for spatio-temporal data](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf)\n\n###  GeoMAN \n\nGeoMAN (Multi-level Attention Networks for Geo-sensory Time Series Prediction) consists of two major parts: 1) A multi-level attention mechanism (including both local and global  spatial attentions in encoder and temporal attention in decoder) to model the dynamic spatio-temporal  dependencies; 2) A general fusion module to incorporate the external factors from different domains (e.g.,  meteorology, time of day and land use).\n\n- Reference Paper:\n\n  + [Liang, Y., Ke, S., Zhang, J., Yi, X., & Zheng, Y. (2018, July). GeoMAN: Multi-level Attention Networks for Geo-sensory Time Series Prediction](https://www.ijcai.org/proceedings/2018/0476.pdf)\n- Reference Implementation:\n  + [An easy implement of GeoMAN using TensorFlow (yoshall & CastleLiang)](https://github.com/yoshall/GeoMAN)\n\n### GMAN\n\nGMAN (Graph Multi-Attention Network) is a deep nerual network for traffic prediction adopting encoder-decoder architecture. Both encode and decoder consist of multiple spatio-temporal attention blocks to model spatio-temporal dependencies.\n\n- Reference Paper:\n  - [Zheng, C., Fan, X., Wang, C., & Qi, J. (2020, April). Gman: A graph multi-attention network for traffic prediction.](https://ojs.aaai.org/index.php/AAAI/article/view/5477)\n- Reference Implementation:\n  - [implementation of Graph Multi-Attention Network](https://github.com/zhengchuanpan/GMAN)\n\n### GraphWaveNet\n\nGraphWaveNet is an end-to-end novel graph neural network. It captures spatial dependencies through a self-adptive adjacency matrix. And it captures temporal dependencies through convolutions.\n\n- Reference Paper:\n  - [Wu, Z., Pan, S., Long, G., Jiang, J., & Zhang, C. (2019). Graph wavenet for deep spatial-temporal graph modeling.](https://www.ijcai.org/proceedings/2019/0264.pdf)\n- Reference Implementation:\n  - [Github repository (nnzhan)](https://github.com/nnzhan/Graph-WaveNet)\n\n###  HM (Historical Mean)\n\nHM is a constant model and always forecasts the sample mean of the historical data.\n\n###  HMM (Hidden Markov Model)\n\nHidden Markov Model is a statistical Markov model in which the system being modeled is assumed to be a Markov process with hidden states. It is often used in temporal pattern recognition.\n\n- Reference Paper:\n\n  + [Chen, Z., Wen, J., & Geng, Y. (2016, November). Predicting future traffic using hidden markov models](https://ieeexplore.ieee.org/abstract/document/7785328)\n- Reference Package: `hmmlearn`\n\n### STGCN \n\nSTGCN (Spatio-temporal Graph Convolutional Networks) is a deep learning framework for traffic forecasting with complete convolutional structures.\n\n- Reference Paper:\n  - [Yu, B., Yin, H., & Zhu, Z. (2017). Spatio-temporal graph convolutional networks: A deep learning framework for traffic forecasting.](https://www.ijcai.org/proceedings/2018/0505.pdf)\n- Reference Implementation:\n  - [Github repository (VeritasYin)](https://github.com/VeritasYin/STGCN_IJCAI-18)\n\n### STMeta\n\nSTMeta is our prediction model, which requires extra graph information as input, and combines Graph Convolution LSTM and Attention mechanism.\n\n- Reference Package: `tensorflow`\n\n### ST-MGCN \n\nST-MGCN (Spatiotemporal Multi-graph Convolution Network) is a deep learning based model which encoded the non-Euclidean correlations among regions using multiple graphs and explicitly captured them using multi-graph convolution.\n\n- Reference Paper:\n\n  + [Geng, X., Li, Y., Wang, L., Zhang, L., Yang, Q., Ye, J., & Liu, Y. (2019). Spatiotemporal multi-graph convolution network for ride-hailing demand forecasting](https://ieeexplore.ieee.org/abstract/document/7785328)\n- Reference Implementation:\n  + [A PyTorch implementation of the ST-MGCN model  (shawnwang-tech)](https://github.com/shawnwang-tech/ST-MGCN-pytorch)\n\n### ST-ResNet\n\nST-ResNet is a deep-learning model with an end-to-end structure based on unique properties of spatio-temporal data making use of convolution and residual units.\n\n- Reference Paper:\n  - [Zhang, J., Zheng, Y., & Qi, D. (2017, February). Deep spatio-temporal residual networks for citywide crowd flows prediction](https://arxiv.org/pdf/1610.00081.pdf)\n- Reference Implementation:\n  - [Github repository (lucktroy)](https://github.com/lucktroy/DeepST/tree/master/scripts/papers/AAAI17)\n\n### STSGCN \n\nSTSGCN (Spatial-temporal Synchronous Graph Convolutional Networks) is a deep learning framework for spatial-temporal network data forecasting. It is able to capture spatial-temporal dependencies through a designed spatial-temporal synchronous modeling mechanism.\n\n- Reference Paper:\n  - [Song, C., Lin, Y., Guo, S., & Wan, H. (2020, April). Spatial-temporal synchronous graph convolutional networks: A new framework for spatial-temporal network data forecasting.](https://ojs.aaai.org/index.php/AAAI/article/view/5438)\n- Reference Implementation:\n  - [Github repository (Davidham3)](https://github.com/Davidham3/STSGCN)\n\n### XGBoost\n\nXGBoost is a gradient boosting machine learning algorithm widely used in flow prediction and other machine learning prediction areas.\n\n- Reference Paper:\n  - [Alajali, W., Zhou, W., Wen, S., & Wang, Y. (2018). Intersection Traffic Prediction Using Decision Tree Models](https://www.mdpi.com/2073-8994/10/9/386)\n- Reference Package: `xgboost`\n\n## Quick Start\n\n### Quick start with STMeta\n\n```python\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n# Config data loader\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', graph='Correlation',\n                                closeness_len=6, period_len=7, trend_len=4, normalize=True)\n\n# Build Graph\ngraph_obj = GraphGenerator(graph='Correlation', data_loader=data_loader)\n\n# Init model object\nSTMeta_Obj = STMeta(closeness_len=data_loader.closeness_len,\n                    period_len=data_loader.period_len,\n                    trend_len=data_loader.trend_len,\n                    num_node=data_loader.station_number,\n                    num_graph=graph_obj.LM.shape[0],\n                    external_dim=data_loader.external_dim)\n\n# Build tf-graph\nSTMeta_Obj.build()\n# Training\nSTMeta_Obj.fit(closeness_feature=data_loader.train_closeness,\n               period_feature=data_loader.train_period,\n               trend_feature=data_loader.train_trend,\n               laplace_matrix=graph_obj.LM,\n               target=data_loader.train_y,\n               external_feature=data_loader.train_ef,\n               sequence_length=data_loader.train_sequence_len)\n\n# Predict\nprediction = STMeta_Obj.predict(closeness_feature=data_loader.test_closeness,\n                                period_feature=data_loader.test_period,\n                                trend_feature=data_loader.test_trend,\n                                laplace_matrix=graph_obj.LM,\n                                target=data_loader.test_y,\n                                external_feature=data_loader.test_ef,\n                                output_names=['prediction'],\n                                sequence_length=data_loader.test_sequence_len)\n\n# Evaluate\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.min_max_denormal(prediction['prediction']),\n                                 target=data_loader.normalizer.min_max_denormal(data_loader.test_y)))\n```\n\n### Quick Start with HM\n\n```python\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import HM\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=1, period_len=1, trend_len=2,\n                                with_lm=False, normalize=False)\n\nhm_obj = HM(c=data_loader.closeness_len, p=data_loader.period_len, t=data_loader.trend_len)\n\nprediction = hm_obj.predict(closeness_feature=data_loader.test_closeness,\n                            period_feature=data_loader.test_period,\n                            trend_feature=data_loader.test_trend)\n\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))\n```\n\n### Quick Start with ARIMA\n\n```python\nimport numpy as np\n\nfrom UCTB.model import ARIMA\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=24, period_len=0, trend_len=0,\n                                with_lm=False, normalize=False)\n\ntest_prediction_collector = []\nfor i in range(data_loader.station_number):\n    try:\n        model_obj = ARIMA(time_sequence=data_loader.train_closeness[:, i, -1, 0],\n                          order=[6, 0, 1], seasonal_order=[0, 0, 0, 0])\n        test_prediction = model_obj.predict(time_sequences=data_loader.test_closeness[:, i, :, 0],\n                                            forecast_step=1)\n    except Exception as e:\n        print('Converge failed with error', e)\n        print('Using last as prediction')\n        test_prediction = data_loader.test_closeness[:, i, -1:, :]\n    test_prediction_collector.append(test_prediction)\n    print('Station', i, 'finished')\n\ntest_rmse = metric.rmse(np.concatenate(test_prediction_collector, axis=-2), data_loader.test_y)\n\nprint('test_rmse', test_rmse)\n```\n\n### Quick Start with HMM\n\n```python\nimport numpy as np\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import HMM\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC',\n                                closeness_len=12, period_len=0, trend_len=0,\n                                with_lm=False, normalize=False)\n\nprediction = []\nfor station_index in range(data_loader.station_number):\n    # train the hmm model\n    try:\n        hmm = HMM(num_components=8, n_iter=100)\n        hmm.fit(data_loader.train_closeness[:, station_index:station_index+1, -1, 0])\n        # predict\n        p = []\n        for time_index in range(data_loader.test_closeness.shape[0]):\n            p.append(hmm.predict(data_loader.test_closeness[time_index, station_index, :, :], length=1))\n    except Exception as e:\n        print('Failed at station', station_index, 'with error', e)\n        # using zero as prediction\n        p = [[[0]] for _ in range(data_loader.test_closeness.shape[0])]\n\n    prediction.append(np.array(p)[:, :, 0])\n    print('Node', station_index, 'finished')\n\nprediction = np.array(prediction).transpose([1, 0, 2])\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))\n```\n\n### Quick Start with XGBoost\n\n```python\nimport numpy as np\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import XGBoost\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=6, period_len=7, trend_len=4,\n                                with_lm=False, normalize=False)\n\nprediction_test = []\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = XGBoost(n_estimators=100, max_depth=3, objective='reg:squarederror')\n\n    model.fit(np.concatenate((data_loader.train_closeness[:, i, :, 0],\n                              data_loader.train_period[:, i, :, 0],\n                              data_loader.train_trend[:, i, :, 0],), axis=-1),\n              data_loader.train_y[:, i, 0])\n\n    p_test = model.predict(np.concatenate((data_loader.test_closeness[:, i, :, 0],\n                                           data_loader.test_period[:, i, :, 0],\n                                           data_loader.test_trend[:, i, :, 0],), axis=-1))\n\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\n\nprediction_test = np.concatenate(prediction_test, axis=-2)\n\nprint('Test RMSE', metric.rmse(prediction_test, data_loader.test_y))\n```\n\n## Tutorial\n\nThe general process of completing a spatiotemporal prediction task includes: loading dataset, defining model, training, testing, model evaluation.\n\n![tutorial](https://uctb.github.io/UCTB/sphinx/md_file/src/image/tutorial.png)\n\n### Load datasets from Urban_dataset\n\nTo help better accuse dataset, UCTB provides data loader APIs `UCTB.dataset.data_loader`, which can be used to preprocess data, including **data division**, **normalization**, and **extract temporal and spatial knowledge**.\n\nIn the following tutorial, we will illustrate how to use `UCTB.dataset.data_loader` APIs to inspect the speed dataset.\n\n```python\nfrom UCTB.dataset.data_loader import NodeTrafficLoader\n```\n\nWe use all(data_range='all') of speed data in METR_LA(Assume that scripts are put under root directory, METR_LA dataset is put under `./data` directory.). Firstly, let's initialize a NodeTrafficLoader object:\n\n```python\ndata_loader = NodeTrafficLoader(city='LA',\n                 data_range='all',\n                 train_data_length='all',\n                 test_ratio=0.1,\n                 closeness_len=6,\n                 period_len=7,\n                 trend_len=4,\n                 target_length=1,\n                 normalize=False,\n                 data_dir='data',\n                 MergeIndex=1,\n                 MergeWay=\"sum\",dataset='METR',remove=False)\n```\n\n\n\nNodeTrafficLoader is the base class for dataset extracting and processing. Input arguments appeared in constructor above will be explained.\n\n- data range selection\n`*data range = 'all'` means that we choose the whole data as our traffic_data to train, test, and predict.\n\n- data spliting(train set and test set spliting)\n\n`train_data length = 'all'` means that we exploit all of the traffic_data. `'train_test_ratio = 0.1` means we divide the dataset into train and test sets. And the train set to the test set is nine to one.\n\n- normalization\n\n`normalization = False` means that we normalized the dataset through min-max-normalization method. When we input False, we simply do not employ any preprocessing tricks on the dataset.\n\n- data merging\n\n`MergeIndex = 1, MergeWay = 'sum'` means that granularity of raw dataset will not be changed. If we try MergeIndex > 1, we can obtain combination of MergeIndex time slots of data in a way of 'sum' or 'average'.\n\n- multiple time series building(temporal knowledge exploiting)\n\n`closeness_len = 6, period_len=7, trend_len=4, target_length=1` means that we create 3 time series, using former consecutive closeness_len time slots of data as a unit, former every other daily_slots time slots of data as a unit(consisting of period_len piece of data), former every other daily_slots*7 time slots of data as a unit(consisting of trend_len piece of data) respectively.\n\n```python\nprint(data_loader.train_closeness.shape)\nprint(data_loader.train_period.shape)\nprint(data_loader.train_trend.shape)\nprint(data_loader.train_data.shape)\n```\n```\n(22780, 207, 6, 1)\n(22780, 207, 7, 1)\n(22780, 207, 4, 1)\n(30844, 207)\n```\nYou may probably note that the length of train_closeness is 13778 less than that of train_data. It's because we choose the shortest data length among the three series(train_trend) for alignment.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/data_reassemble.png\" style=\"zoom: 10%;\" />\n\nAbove is the visualization of a new time series's construction. In this situation, feature_stride = 3(means sampling interval), feature_step = 3(means how many times we sample).Other time series are just the same situation.\n\nThrough the process in the figure shown above, we can calculate the length of train_trend is $30844-12*24*7*4=22780$, which is the minimum among three time series.\n\n**Operations**\n\n- Denormalization/Normalization\n- Visualization\n- Temporal Knowledge Exploitation\n- Spatial knowledge Exploration\n- Access to raw data\n\n```python\nimport matplotlib.pyplot as plt\nfrom UCTB.preprocess.preprocessor import Normalizer\n\n# without normalization\n\ntarget_node = 5\nplt.plot(data_loader.traffic_data[:,5])\nplt.title('Raw')\nplt.show()\n\n# normalization\n\nnormalizer=Normalizer(data_loader.traffic_data)\nX_normalized = normalizer.min_max_normal(data_loader.traffic_data)\n\n# denormalization\n\nX_denormalized = normalizer.min_max_denormal(X_normalized)\n\nplt.plot(X_normalized[:,5])\nplt.title('Normalized')\nplt.show()\nplt.plot(X_denormalized[:,5])\nplt.title('Denormalized')\nplt.show()\n```\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Raw_data.png\" alt=\"Raw_data\" style=\"zoom:33%;\" /><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/normalized_data.png\" style=\"zoom:33%;\" /><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/denormalized_data.png\" style=\"zoom:33%;\" />\n\n```python\n# Nodes' location visualizations\ndata_loader.st_map()\n```\n\nVisualization result is as follows:\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/METR_LA.png\" alt=\"Node location of METR_LA\" style=\"zoom: 50%;\" />\n\n```python\n# data visualization\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nreal_denormed=data_loader.normalizer.min_max_denormal(data_loader.test_y)\nsns.heatmap(real_denormed[:,:,0], cmap='Reds', vmin = -1000, vmax = 4000)\nplt.ylabel(\"Time Slot\")\nplt.xlabel(\"Sensor Node\")\nplt.title(\"Visualization\")\nplt.show()\n```\n\n```python\n# Feature stitching\nX = data_loader.make_concat()\nprint('before concatenate')\nprint('closeness')\nprint(data_loader.train_closeness.shape)\nprint('period')\nprint(data_loader.train_period.shape)\nprint('trend')\nprint(data_loader.train_trend.shape)\nprint('After concatenate')\nprint(X.shape)\n```\n```\nbefore concatenate\ncloseness\n(22780, 207, 6, 1)\nperiod\n(22780, 207, 7, 1)\ntrend\n(22780, 207, 4, 1)\nAfter concatenate\n(22780, 207, 17, 1)\n```\n```python\n# access to raw data\nprint(data_loader.traffic_data[0,0])\n```\n\n```\n64.375\n```\n\n### Model definition, train, test and evaluation\n\nWe use XGBoost interface in UCTB as an example to define a model. Since there are total 207 stations in METR_LA dataset, we define 207 XGBoost models respectively. They are trained and tested in their own iteration related to stations. Finally, when we evaluate our model, we consider the prediction results as a whole and evaluate it against GroundTruth provided by `data_loader` using [RMSE](https://en.wikipedia.org/wiki/Root-mean-square_deviation) metric.\n\n```python\n\nfrom UCTB.evaluation import metric\nfrom UCTB.model import XGBoost\nimport UCTB.evaluation.metric as metric\nprediction_test = []\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = XGBoost(n_estimators=100, max_depth=3, objective='reg:squarederror')\n\n    model.fit(np.concatenate((data_loader.train_closeness[:, i, :, 0],\n                              data_loader.train_period[:, i, :, 0],\n                              data_loader.train_trend[:, i, :, 0],), axis=-1),\n              data_loader.train_y[:, i, 0])\n\n    p_test = model.predict(np.concatenate((data_loader.test_closeness[:, i, :, 0],\n                                           data_loader.test_period[:, i, :, 0],\n                                           data_loader.test_trend[:, i, :, 0],), axis=-1))\n\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\n\nprediction_test = np.concatenate(prediction_test, axis=-2)\n\ny_truth = data_loader.normalizer.inverse_transform(data_loader.test_y)\ny_pred = data_loader.normalizer.inverse_transform(prediction_test)\ny_truth = y_truth.reshape([-1,207])\ny_pred = y_pred.reshape([-1,207])\nprint('Test RMSE', metric.rmse(y_pred, y_truth))\nplt.title('XGBoost Result')\nplt.xlabel('Time Slot')\nplt.ylabel('Speed')\nplt.plot(y_pred[:12*24*7,target_node])\nplt.plot(y_truth[:12*24*7,target_node])\nplt.legend(['gt','pred'])\nplt.show()\n```\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/XGBoost_Result.png\" alt=\"XGBoost Result\" style=\"zoom:50%;\" />\n\n```\nTest RMSE 5.549781682961724\n```\n\n### Single vs. Multiple kinds of temporal knowledge\n\n#### Use temporal closeness feature in regression\n\nUCTB provides many classical and popular spatial-temporal predicting models. These models can be used to either predicting series for a single station or all stations. You can find the details in [``UCTB.model``](./static/current_supported_models.html).\n\nThe following example shows how to use a **XGBoost** model to handle a simple time series predicting a problem. We will try to predict the bike demands ``test_y`` of a fixed station ``target_node`` in New York City by checking back the historical demands in recent time slots ``train_closeness``.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom UCTB.model import XGBoost\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\ntarget_node = 233\n```\n\nWhen initializing the loader, we use past ``12`` time slots (timesteps) of closeness as input, ``1`` timestep in the next as output and set the timesteps of other features ``period_len``, ``period_len`` to zero. \n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=12, period_len=0, trend_len=0,\n                                target_length=1, test_ratio=0.2, \n                                normalize=False, with_lm=False, with_tpe=False)\n```\n\nThe well-loaded data contain all ``717`` stations' data. Therefore it is needed to specify the target station by ``target_station``.\n\n```python\nprint(data_loader.train_closeness.shape)\nprint(data_loader.test_closeness.shape)\nprint(data_loader.test_y.shape)\n```\n\n```python\n(2967, 717, 12, 1)\n(745, 717, 12, 1)\n(745, 717, 1)\n```\n\n\n```python\ntrain_x, test_x = data_loader.train_closeness[:, target_node, :, 0], data_loader.test_closeness[:, target_node, :, 0]\ntrain_y = data_loader.train_y[:, target_node,0]\ntest_y = data_loader.test_y[:, target_node, 0]\n```\n\nInspect the shape of data. Here are the all we need for one-station prediction.\n\n\n```python\nprint(train_x.shape)\nprint(train_y.shape)\nprint(test_x.shape)\nprint(test_y.shape)\n```\n\n    (2967, 12)\n    (2967,)\n    (745, 12)\n    (745,)\n\nBuild the XGBoost model.\n\n```python\nmodel = XGBoost(n_estimators=100, max_depth=3, objective='reg:linear')\n```\n\nNow, we can fit the model with the train dataset and make predictions on the test dataset.\n\n```python\nmodel.fit(x=train_x)\npredictions = model.predict(test_x)\n```\n\nWe can evaluate the performance of the model by build-in ``UCTB.evaluation`` APIs.\n\n```python\ntest_rmse = metric.rmse(predictions, test_y)\nprint(test_rmse)\n```\n\n    3.6033132\n\n#### Make full use of closeness, period, and trend features \n\nIn this case, let's take more temporal knowledge related to ``target_node`` into account. We will concatenate factors including ``closeness``, ``period``, and ``trend``, and use **XGBoost** as the predicting model.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom UCTB.model import XGBoost\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\ntarget_node = 233\n\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=6, period_len=7, trend_len=4,\n                                target_length=1, test_ratio=0.2, \n                                normalize=False, with_lm=False, with_tpe=False)\n\ntrain_closeness = data_loader.train_closeness[:, target_node, :, 0]\ntrain_period = data_loader.train_period[:, target_nodze, :, 0]\ntrain_trend = data_loader.train_trend[:, target_node, :, 0]\ntrain_y = data_loader.train_y[:, target_node, 0]\n\ntest_closeness = data_loader.test_closeness[:, target_node, :, 0]\ntest_period = data_loader.test_period[:, target_node, :, 0]\ntest_trend = data_loader.test_trend[:, target_node, :, 0]\ntest_y = data_loader.test_y[:, target_node, 0]\n\ntrain_X = np.concatenate([train_closeness, train_period, train_trend], axis=-1)\ntest_X = np.concatenate([test_closeness, test_period, test_trend], axis=-1)\n\nprint(train_X.shape)\nprint(train_y.shape)\nprint(test_X.shape)\nprint(test_y.shape)\n\nmodel = XGBoost(n_estimators=100, max_depth=3, objective='reg:linear')\nmodel.fit(train_X, train_y)\npredictions = model.predict(test_X)\nprint('Test RMSE', metric.rmse(predictions, test_y))\n```\n\n    (2307, 17)\n    (2307,)\n    (745, 17)\n    (745,)\n    Test RMSE 3.3267457\n## Advanced Features\n\n### Build your own model using UCTB\n\nUCTB provides extendable APIs to build your own model. Currently, it can support the running of all the ``1.x`` version of **Tensorflow-based** models. In the following tutorial, we will show you how to takes the least efforts to implement a UCTB model.\n\nCommonly, a new model needs to inherit ``BaseModel`` to acquire the features provided by UCTB, such as batch division, early stopping, etc. The necessary components for a subclass of ``BaseModel`` include:\n\n- ``self.__init__()``. Define the model's parameters related to the architecture. You should call the super class's constructor at first.\n- ``self.build()``. Build the architecture here. You should construct the graph at the beginning of this function and call the super class's ``build()`` function at the end.\n- ``self._input``. The ``dict`` used to record the acceptable inputs of the model, whose keys are the parameter names in ``model.fit()`` and ``model.predict()`` and values are the name of related tensors.\n- ``self._output``. The ``dict`` used to record the outputs of the model. You should fill the required keys ``prediction`` and ``loss`` with the names of tensors in your case.\n- ``self._op``. The ``dict`` used to define all the operations for the model. Basic usage for it is to record the **training operation**, for example, the minimizing loss operation of an optimizer. Use key ``train_op`` to record it.\n\nFor more examples, you can refer to the implementations of build-in models in [``UCTB.model``](../UCTB.model.html#uctb-model-package).\n\n\n```python\nfrom UCTB.model_unit import BaseModel\n\nclass MyModel(BaseModel):\n    def __init__(self,\n                 \n                 code_version='0',\n                 model_dir='my_model',\n                 gpu_device='0',\n                ):\n        super(MyModel, self).__init__(code_version=code_version, \n                                      model_dir=model_dir, gpu_device=gpu_device)\n        ...\n        \n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            ...\n            self._input['inputs'] = inputs.name\n            self._input['targets'] = targets.name\n            \n            ...\n            self._output['prediction'] = predictions.name\n            self._output['loss'] = loss.name\n            self._op['train_op'] = train_op.name\n            \n        super(MyModel, self).build(init_vars=init_vars, max_to_keep=5) \n```\n\nNext, in a concrete case, we will realize a **Long short-term memory (LSTM)** model to make the all-station prediction that accepts time series of `717` stations and predict the future of them as a whole. \n\nFor the mechanism of LSTM, you can refer to \n[Gers, F. A., Schmidhuber, J., & Cummins, F. (1999). Learning to forget: Continual prediction with LSTM](https://www.researchgate.net/profile/Felix_Gers/publication/12292425_Learning_to_Forget_Continual_Prediction_with_LSTM/links/5759414608ae9a9c954e84c5/Learning-to-Forget-Continual-Prediction-with-LSTM.pdf).\n\n\n```python\nimport numpy as np\nimport tensorflow as tf\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model_unit import BaseModel\nfrom UCTB.preprocess import SplitData\nfrom UCTB.evaluation import metric\n```\n\n\n```python\nclass LSTM(BaseModel):\n    def __init__(self,\n                 num_stations, \n                 num_layers, \n                 num_units, \n                 input_steps, \n                 input_dim,\n                 output_steps,\n                 output_dim,\n                 code_version='0',\n                 model_dir='my_lstm',\n                 gpu_device='0'):\n        super(LSTM, self).__init__(code_version=code_version, \n                                   model_dir=model_dir, gpu_device=gpu_device)\n        self.num_stations = num_stations\n        self.num_layers = num_layers\n        self.num_units = num_units\n        self.input_steps = input_steps\n        self.input_dim = input_dim\n        self.output_steps = output_steps\n        self.output_dim = output_dim\n        \n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            inputs = tf.placeholder(tf.float32, shape=(None, self.num_stations, \n                                                       self.input_steps, self.input_dim))\n            targets = tf.placeholder(tf.float32, shape=(None, self.num_stations,\n                                                       self.output_steps, self.output_dim))\n            # record the inputs of the model\n            self._input['inputs'] = inputs.name\n            self._input['targets'] = targets.name\n\n            inputs = tf.reshape(inputs, (-1, self.input_steps, self.num_stations*self.input_dim))\n            \n            def get_a_cell(num_units):\n                lstm = tf.nn.rnn_cell.BasicLSTMCell(num_units, state_is_tuple=True)\n                return lstm\n            \n            stacked_cells = tf.contrib.rnn.MultiRNNCell([get_a_cell(self.num_units) for _ in range(self.num_layers)], state_is_tuple=True)\n            outputs, final_state = tf.nn.dynamic_rnn(stacked_cells, inputs, dtype=tf.float32)\n            \n            stacked_outputs = tf.reshape(outputs, shape=(-1, self.num_units*self.input_steps))\n            predictions = tf.layers.dense(stacked_outputs, self.output_steps*self.num_stations*self.output_dim)\n            predictions = tf.reshape(predictions, shape=(-1, self.num_stations, self.output_steps, self.output_dim))\n            \n            loss = tf.sqrt(tf.reduce_mean(tf.square(predictions - targets)))\n            train_op = tf.train.AdamOptimizer().minimize(loss)\n            \n            # record the outputs and the operation of the model\n            self._output['prediction'] = predictions.name\n            self._output['loss'] = loss.name\n            self._op['train_op'] = train_op.name\n        \n        # must call super class' function to build \n        super(LSTM, self).build(init_vars=init_vars, max_to_keep=5) \n```\n\nLoad the dataset by loader and transform them into the formats your model accepts. If the loader APIs are not filled your demands, you can inherit loader and wrapper it according to your desires (see [Quickstart](./quickstart.html) for more details).\n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=6, period_len=0, trend_len=0,\n                                target_length=1, test_ratio=0.2, \n                                normalize=True, with_lm=False, with_tpe=False)\ntrain_y = np.expand_dims(data_loader.train_y, axis=-1)\ntest_y = np.expand_dims(data_loader.test_y, axis=-1)\n```\n\n\n```python\nmodel = LSTM(num_stations=data_loader.station_number, \n             num_layers=2,\n             num_units=512, \n             input_steps=6, \n             input_dim=1, \n             output_steps=1, \n             output_dim=1)\n```\n\n\n```python\nmodel.build()\nprint(model.trainable_vars)  # count the trainble parameters\n```\n\n    6821581\n\nUse your model to training and predicting. ``model.fit()`` method presets lots of useful functions, such as batch division and early stopping. Check them in [``UCTB.model_unit.BaseModel.BaseModel.fit``](../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.fit).\n\n\n```python\nmodel.fit(inputs=data_loader.train_closeness,\n          targets=train_y,\n          max_epoch=10,\n          batch_size=64,\n          sequence_length=data_loader.train_sequence_len,\n          validate_ratio=0.1)\n```\n\n    No model found, start training\n    Running Operation ('train_op',)\n    Epoch 0: train_loss 0.016053785 val_loss 0.01606118\n    Epoch 1: train_loss 0.015499311 val_loss 0.015820855\n    Epoch 2: train_loss 0.015298592 val_loss 0.015657894\n    Epoch 3: train_loss 0.015163456 val_loss 0.015559187\n    Epoch 4: train_loss 0.015066812 val_loss 0.015342651\n    Epoch 5: train_loss 0.015016247 val_loss 0.015287879\n    Epoch 6: train_loss 0.014899823 val_loss 0.015249459\n    Epoch 7: train_loss 0.014773054 val_loss 0.015098239\n    Epoch 8: train_loss 0.014655286 val_loss 0.015097916\n    Epoch 9: train_loss 0.014558283 val_loss 0.015108417\n\n```python\npredictions = model.predict(inputs=data_loader.test_closeness, \n                            sequence_length=data_loader.test_sequence_len)\n```\n\nReverse the normalization by ``data_loader`` and evaluate the results:\n\n\n```python\npredictions = data_loader.normalizer.inverse_transform(predictions['prediction'])\ntargets = data_loader.normalizer.inverse_transform(test_y)\nprint('Test result', metric.rmse(prediction=predictions, target=targets))\n```\n\n    Test result 2.9765626570592545\n\nSince we only use a short period of the dataset (``data_range=0.1``) in this toy example, the result looks good compared with the [experiment](./all_results.html#results-on-bike). You can also take a try to test the completed dataset on your model. \n\n### Build your own graph with STMeta\n\nNext, we will use the Top-K graph as an example to illustrate how to build customized graphs in UCTB. All of the code in this section can be found [here](https://anonymous.4open.science/r/561305b5-e65e-46c6-9371-ae76b85109ee/Experiments/CustomizedDemo/).\n\n**Top-K graph**\n\nFirst of all, the customized graphs used in this section is called Top-K graph. We construct the corresponding adjacent graph by marking the point pair that consist of each point and its nearest K points as 1, and the others are marked as 0. Then, we use the adjacent graph to generate the laplacian matrix for input. The hyperparameter K is designed via ad-hoc heuristics. In this demonstration, we chose 23 as the value of K.\n\n**Realize TopK graph analysis module**\n\nTo adopt customized graphs (***e.g.,*** Top-K) in UCTB, you should first build your own analysis class by inheriting `UCTB.preprocess.GraphGenerator class`.\n\nIt is worth noting that the ultimate goal is to generate the member variables: `self.LM` and `self.AM`, which is the input matrix of the graph. In this phase, we need to make the corresponding analytical implementation according to the type of the custom graph passed in.\n\n ```python\n# \"UCTB/preprocess/topKGraph.py\"\nimport heapq\nimport numpy as np\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n\n# Define the class: topKGraph\nclass topKGraph(GraphGenerator):  # Init NodeTrafficLoader\n\n    def __init__(self,**kwargs):\n\n        super(topKGraph, self).__init__(**kwargs)\n        \n        for graph_name in kwargs['graph'].split('-'):\n\n# As the basic graph is implemented in GraphGenerator, you only need to implement your own graph function instead of the existing one.\n            if graph_name.lower() == 'topk':\n                lat_lng_list = np.array([[float(e1) for e1 in e[2:4]]\n                                         for e in self.dataset.node_station_info])\n                # Handling\n                AM = self.neighbour_adjacent(lat_lng_list[self.traffic_data_index],\n                                        threshold=int(kwargs['threshold_neighbour']))\n                LM = self.adjacent_to_laplacian(AM)\n\n                if self.AM.shape[0] == 0:  # Make AM\n                    self.AM = np.array([AM], dtype=np.float32)\n                else:\n                    self.AM = np.vstack((self.AM, (AM[np.newaxis, :])))\n\n                if self.LM.shape[0] == 0:  # Make LM\n                    self.LM = np.array([LM], dtype=np.float32)\n                else:\n                    self.LM = np.vstack((self.LM, (LM[np.newaxis, :])))\n\n# Implement the details of building the Top-K graph.\n    def neighbour_adjacent(self, lat_lng_list, threshold):\n        adjacent_matrix = np.zeros([len(lat_lng_list), len(lat_lng_list)])\n        for i in range(len(lat_lng_list)):\n            for j in range(len(lat_lng_list)):\n                adjacent_matrix[i][j] = self.haversine(\n                    lat_lng_list[i][0], lat_lng_list[i][1], lat_lng_list[j][0], lat_lng_list[j][1])\n        dis_matrix = adjacent_matrix.astype(np.float32)\n\n        for i in range(len(dis_matrix)):\n            ind = heapq.nlargest(threshold, range(len(dis_matrix[i])), dis_matrix[i].take)\n            dis_matrix[i] = np.array([0 for _ in range(len(dis_matrix[i]))])\n            dis_matrix[i][ind] = 1\n        adjacent_matrix = (adjacent_matrix == 1).astype(np.float32)\n        return adjacent_matrix\n ```\n\n**Redefine the call statement of the above class**\n\n```python\n# \"UCTB/Experiments/CustomizedDemo/STMeta_Obj_topk.py\"\n\n# Import the Class: topKGraph\nfrom topKGraph import topKGraph\n# Call topKGraph to initialize and generate AM and LM\ngraphBuilder = topKGraph(graph=args['graph'],\n                         data_loader=data_loader,\n                         threshold_distance=args['threshold_distance'],\n                         threshold_correlation=args['threshold_correlation'],\n                         threshold_interaction=args['threshold_interaction'],\n                         threshold_neighbour=args['threshold_neighbour'])\n# ......\n```\n\n**Modify the function call location**\n\nAdd the new graph name when fitting model and then execute it for experiments. [code](https://github.com/uctb/UCTB/blob/master/Experiments/CustomizedDemo/Runner_topk.py)\n\n```python\nos.system('python STMeta_Obj_topk.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line-TopK,MergeIndex:12')\n```\n\nWe conduct experiments on `Metro_Shanghai` dataset and use the [STMeta_V1](https://uctb.github.io/UCTB/md_file/all_results.html#stmeta-version) to model both \"Distance-Correlation-Line\" graph and \"Distance-Correlation-Line-TopK\" and the results are following:\n\n| **Metro: Shanghai** |             Graph              | Test-RMSE |\n| :-----------------: | :----------------------------: | :-------: |\n|      STMeta_V1      |   Distance-Correlation-Line    |  153.17   |\n|      STMeta_V1      | Distance-Correlation-Line-TopK |  140.82   |\n\nThe results show that the performance of STMeta_V1 with the graph \"Distance-Correlation-Line-TopK\" is better than \"Distance-Correlation-Line\" model and the RMSE is reduced by about 12.4%, which validates the effectiveness of the topk graph for spatiotemporal modeling STMeta algorithm.\n\n------\n\n<u>[Back To HomePage](../index.html)</u>\n\n"
  },
  {
    "path": "docs/_sources/md_file/quickstart.md.txt",
    "content": "## Quick start\n\n#### Quick start with STMeta\n\n```python\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n# Config data loader\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', graph='Correlation',\n                                closeness_len=6, period_len=7, trend_len=4, normalize=True)\n\n# Build Graph\ngraph_obj = GraphGenerator(graph='Correlation', data_loader=data_loader)\n\n# Init model object\nSTMeta_Obj = STMeta(closeness_len=data_loader.closeness_len,\n                    period_len=data_loader.period_len,\n                    trend_len=data_loader.trend_len,\n                    num_node=data_loader.station_number,\n                    num_graph=graph_obj.LM.shape[0],\n                    external_dim=data_loader.external_dim)\n\n# Build tf-graph\nSTMeta_Obj.build()\n# Training\nSTMeta_Obj.fit(closeness_feature=data_loader.train_closeness,\n               period_feature=data_loader.train_period,\n               trend_feature=data_loader.train_trend,\n               laplace_matrix=graph_obj.LM,\n               target=data_loader.train_y,\n               external_feature=data_loader.train_ef,\n               sequence_length=data_loader.train_sequence_len)\n\n# Predict\nprediction = STMeta_Obj.predict(closeness_feature=data_loader.test_closeness,\n                                period_feature=data_loader.test_period,\n                                trend_feature=data_loader.test_trend,\n                                laplace_matrix=graph_obj.LM,\n                                target=data_loader.test_y,\n                                external_feature=data_loader.test_ef,\n                                output_names=['prediction'],\n                                sequence_length=data_loader.test_sequence_len)\n\n# Evaluate\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.min_max_denormal(prediction['prediction']),\n                                 target=data_loader.normalizer.min_max_denormal(data_loader.test_y)))\n\n```\n\n#### [Quick start with other models](./static/quick_start.html)\n\n\n\n"
  },
  {
    "path": "docs/_sources/md_file/src/image/README.md.txt",
    "content": "Image resources\n\n"
  },
  {
    "path": "docs/_sources/md_file/static/MakeDatasetDiDi.md.txt",
    "content": "#### DiDi Data\n\nWe are especially grateful for the data provided by the DiDi Chuxing GAIA Initiative.\n\nThis dataset is from the trajectory data of DiDi Express and DiDi Premier drivers within the Second Ring Road of Xi'an and Chengdu City. The measurement interval of the track points is approximately 2-4 seconds . The track points were bound to physical roads so that the trajectory data and the actual road information are matched. The driver and trip order information were encrypted and anonymized. \n\n**Step 1**, download data from [https://outreach.didichuxing.com/appEn-vue/dataList](https://outreach.didichuxing.com/appEn-vue/dataList), and put the data into the DiDiData dir.\n\nXi'an City: (download both)<br>\n    [Oct 2016, Xi’an City Second Ring Road Regional Trajectory Data Set](https://outreach.didichuxing.com/appEn-vue/XiAnOct2016?id=8) <br>    [Nov 2016, Xi’an City Second Ring Road Regional Trajectory Data Set](https://outreach.didichuxing.com/appEn-vue/XiAnNov2016?id=9) <br>Chengdu City: (download both)<br>\n    [Oct 2016, Chengdu City Second Ring Road Regional Trajectory Data Set](https://outreach.didichuxing.com/appEn-vue/ChengDuOct2016?id=7) <br>\n    [Nov 2016, Chengdu City Second Ring Road Regional Trajectory Data Set](https://outreach.didichuxing.com/appEn-vue/personal?id=2) \n\nAfter step1, you will have the following file-tree:\n\n```\n├── DiDiData\n│   ├── chengdu\n│   │   ├── chengdu_gps_20161001.json\n│   │   ├── chengdu_gps_20161002.json\n│   │   ├── ...\n│   │   └── chengdu_gps_20161130.json\n│   └── xian\n│       ├── xian_gps_20161001.json\n│       ├── xian_gps_20161002.json\n│       ├── ...\n│       └── xian_gps_20161130.json\n├── release_data_dir\n├── create_release_data_didi.py\n├── data_config.py\n├── get_grid_data_didi.py\n├── get_monthly_interaction_didi.py\n├── local_path.py\n└── multi_threads.py\n```\n\n**Step 2**, run the following codes\n\n```python\n# build the grid data\npython get_grid_data_didi.py --data DiDi --city Xian --jobs 1\npython get_grid_data_didi.py --data DiDi --city Chengdu --jobs 1\n\n# build the monthly interaction data\npython get_monthly_interaction_didi.py --data DiDi --city Xian --jobs 1\npython get_monthly_interaction_didi.py --data DiDi --city Chengdu --jobs 1\n\n# Output the final file\npython create_release_data_didi.py --data DiDi --city Xian\npython create_release_data_didi.py --data DiDi --city Chengdu\n```\n\n`jobs` is the number of threads used by the program. A larger `jobs` will reduce the running time significantly.\n\nYou will see the `.pkl` data in `release_data_dir` after step 2.\n\n"
  },
  {
    "path": "docs/_sources/md_file/static/MakeDatasetDiDi_TTI.md.txt",
    "content": "#### DiDi TTI Data\n\nWe are especially grateful for the data provided by the DiDi Chuxing GAIA Initiative.\n\nThis dataset provides travel time index data for cities in Shenzhen, Chengdu, Xi'an, Suzhou, Ji'nan and Haikou in 2018, including city level, district level, road level, and average driving speed. \n\n**Step 1**, select the `城市交通指数(新)` dataset from [https://outreach.didichuxing.com/app-vue/DataList](https://outreach.didichuxing.com/app-vue/DataList),  download TTI data for Shenzhen, Chengdu, Xi'an, Suzhou, Ji'nan and Haikou, and unzip the data(including road.zip in every  subdirectory) into the DiDiData dir.\n\nAfter step1, you will have the following file-tree:\n\n```\n├─DiDiData\n│  ├─成都市\n│  │      .DS_Store\n│  │      boundary.txt\n│  │      city_district.txt\n│  │      readME.txt\n│  │      成都市.txt\n│  │\n│  ├─济南市\n│  │      .DS_Store\n│  │      boundary.txt\n│  │      city_district.txt\n│  │      readME.txt\n│  │      济南市.txt\n│  │\n│  ├─海口市\n│  │      .DS_Store\n│  │      boundary.txt\n│  │      city_district.txt\n│  │      readME.txt\n│  │      海口市.txt\n│  │\n│  ├─深圳市\n│  │      .DS_Store\n│  │      boundary.txt\n│  │      city_district.txt\n│  │      readME.txt\n│  │\n│  ├─苏州市\n│  │      .DS_Store\n│  │      boundary.txt\n│  │      city_district.txt\n│  │      readME.txt\n│  │      苏州市.txt\n│  │\n│  └─西安市\n│          .DS_Store\n│          boundary.txt\n│          city_district.txt\n│          readME.txt\n│          西安市.txt\n│\n└─release_data_dir\n│        README.md\n│\n│  DiDiTTI_utils.py\n│  processingDiDiTTI.ipynb\n│  README.md\n│  StrictDataFormat.py\n```\n\n**Step 2**, use jupyter notebook to open [processingDiDiTTI.ipynb](../../../DataProcessing/DiDi_TTI/processingDiDiTTI.ipynb), and follow the instructions in the notebook.\n\nFollowing are the details to note:\n\n1. For missing values in the dataset, we use the data from the previous week or the next week to fill.\n2.  According to [TTI Calculation](https://github.com/didi/TrafficIndex), when the road is congested, the actual speed is very slow and TTI value will become abnormally large, so we take  the reciprocal of TTI value to make the pattern more obvious.\n\nYou will see the `.pkl` data in `release_data_dir` after step 2.\n\n"
  },
  {
    "path": "docs/_sources/md_file/static/all_results.md.txt",
    "content": "# Results on different datasets\n\n## STMeta Version\n\nAs introduced in [currently supported models](../static/current_supported_models.html#stmeta), STMeta is a meta-model that can be implemented by different deep learning techniques based on its applications. Here we realize three versions of STMeta to evaluate its generalizability. The main differences between these three variants are the techniques used in spatio-temporal modeling and aggregation units:\n\n| Version Name |                     Spatio-Temporal Unit                     |                  Temporal Aggregation Unit                   | Spatial Aggregation Unit |\n| :----------: | :----------------------------------------------------------: | :----------------------------------------------------------: | :----------------------: |\n|  STMeta-V1   | [GCLSTM](../../UCTB.model_unit.html?highlight=gclstmcel#UCTB.model_unit.ST_RNN.GCLSTMCelll) | [GAL](../../UCTB.model_unit.html?highlight=gclstmcel#UCTB.model_unit.GraphModelLayers.GA) |           GAL            |\n|  STMeta-V2   |                            GCLSTM                            |                        Concat & Dense                        |           GAL            |\n|  STMeta-V3   | [DCGRU](../../UCTB.model_unit.html?highlight=gclstmcel#UCTB.model_unit.DCRNN_CELL.DCGRUCell) |                             GAL                              |           GAL            |\n\nBy default, we use `STMeta-V1` to run LSTM and single graph model tests.\n\nReferences:\n\n- GCLSTM (Graph Convolutional Long short-term Memory):\n\n  [Chai, D., Wang, L., & Yang, Q. (2018, November). Bike flow prediction with multi-graph convolutional networks](https://arxiv.org/pdf/1807.10934) \n\n- DCGRU (Diffusion Convolutional Gated Recurrent Unit):\n\n  [Li, Y., Yu, R., Shahabi, C., & Liu, Y. (2017). Diffusion convolutional recurrent neural network: Data-driven traffic forecasting](https://arxiv.org/pdf/1707.01926.pdf)  \n\n- GAL (Graph Attention Layer):\n\n  [Veličković, P., Cucurull, G., Casanova, A., Romero, A., Lio, P., & Bengio, Y. (2017). Graph attention networks](https://arxiv.org/pdf/1710.10903.pdf) \n\n\n\n## Search Space\n\n|      Model       |                         Search Space                         |\n| :--------------: | :----------------------------------------------------------: |\n|        HM        |               `CT: 0~6`, `PT: 0~7`, `TT: 0~4`                |\n|      ARIMA       |                                                              |\n|       HMM        |                                                              |\n|    ST_ResNet     |                           `待补充`                           |\n|     XGBoost      | `CT: 0~12`, `PT: 0~14`, `TT: 0~4`, `estimater: 10~200`, `depth: 2~10` |\n|       GBRT       | `CT: 0~12`, `PT: 0~14`, `TT: 0~4`, `estimater: 10~200`, `depth: 2~10` |\n|       LSTM       | `lstm_layers: 1~3`, `lstm_hidden_units: 32~128 `, `dense_units: 32~128`, `temp_merge_heads: 2~4`, `temp_merge_units: 32~128` |\n| STMeta-V1 | `gcn_k: 1~3`, `gcn_l: 1~3` `gclstm_layers: 1~3`, `lstm_hidden_units: 64~256 `, `dense_units: 32~128`, `temp_merge_heads: 2~4`, `temp_merge_units: 32~128` |\n\n## Results on Bike\n\n|                                     |          NYC           |         Chicago         |           DC            |\n| :---------------------------------: | :--------------------: | :---------------------: | :---------------------: |\n|                 HM                  |    3.99224 `1-1-3`     |     2.97693 `1-1-2`     |     2.63165 `2-1-3`     |\n|              ARIMA(C)               |        5.60928         |         3.83584         |         3.60450         |\n|             ARIMA(CPT)              |        5.16804         |         3.68593         |         3.08102         |\n|     SARIMA((3,0,1), (1,0,0,24))     |        4.67416         |         3.35526         |         3.02791         |\n|               XGBoost               | 4.12407 `12-10-0-20-5` |  2.92569 `9-7-0-20-5`   | 2.65671 `12-14-2-20-5`  |\n|                GBRT                 | 3.99907 `12-7-4-100-5` | 2.84257 `12-14-2-100-5` | 2.61768 `12-14-2-100-5` |\n|           ST_MGCN (G/DCI)           |        3.72380         |         2.88300         |         2.48560         |\n|            DCRNN(G/D C)             |        4.18666         |         3.27759         |         3.08616         |\n|           DCRNN(G/C CPT)            |        3.87324         |         2.95404         |         2.42749         |\n|              LSTM (C)               |        4.55677         |         3.37004         |         2.91518         |\n|             LSTM (CPT)              |        3.78497         |         2.79078         |         2.54752         |\n|              GRU(CPT)               |        3.53425         |         2.76421         |         2.54121         |\n|              DG-GCLSTM              |        3.63207         |         2.71876         |         2.53863         |\n|              IG-GCLSTM              |        3.78816         |         2.70131         |         2.46214         |\n|              CG-GCLSTM              |        3.69656         |         2.79812         |         2.45815         |\n| STMeta-V1 `1-1-1-64-32-2-64` |        3.50475         |       **2.65511**       |         2.42582         |\n| STMeta-V1 `2-1-1-64-32-2-64` |        3.51352         |         2.76366         |         2.44217         |\n|          STMeta-V2           |      **3.43870**       |         2.66379         |         2.41111         |\n|          STMeta-V3           |        3.47834         |         2.66180         |       **2.38844**       |\n\n#### Parameter Search on bike\n\n| **NYC** (Training data = 1 year) | gcn_k=1 | gcn_k=2 | gcn_k=3 |\n| :------------------------------: | :-----: | :-----: | :-----: |\n|          batch_size=16           |         |         |         |\n|          batch_size=32           |         |         |         |\n|          batch_size=64           |         |         |         |\n\n## Results on DiDi\n\n| <font color='#ff0000'>**City: Xi'an**</font> |            Params            |  val-rmse   | test-rmse | \\# Params |      Converged Time       |\n| :------------------------------------------: | :--------------------------: | :---------: | :-------: | :-------: | :-----------------------: |\n|                      HM                      |          `1-1-2` ✅           |   6.82453   |  6.18623  |    ---    |            ---            |\n|                   ARIMA(C)                   |              --              |   8.87565   |  9.47478  |    --     |            --             |\n|                 ARIMA (CPT)                  |              --              |   7.96953   |  7.47729  |    ---    |            ---            |\n|          SARIMA (3,0,1), (1,0,0,24)          |                              |   7.85844   |  7.61127  |           |                           |\n|                   XGBoost                    |       `12-0-2-10-5 `✅        |   6.90805   |  6.73346  |    ---    |            ---            |\n|                     GBRT                     |        `9-0-2-50-2 `✅        |   6.95321   |  6.44639  |    ---    |            ---            |\n|                  ST-ResNet                   |          ✅ `待补充`          | **6.41107** |  6.08476  | `待补充`  |         0.55 hour         |\n|               ST_MGCN (G/DCI)                |           `待补充`           |   7.51881   |  5.87456  |  248985   |   1.31 hour 300 epochs    |\n|                DCRNN (G/D C)                 |                              |   7.29442   |  8.20254  |   50368   | 2.10 hour / 10000 epochs  |\n|               DCRNN (G/C CPT)                |             ---              |   8.47345   |  6.26264  |  149056   | 12.01 hour / 7930 epochs  |\n|                   LSTM(C)                    |        `1-64-32-2-64`        |   6.52844   |  7.39970  |   28992   |  6.09 hour 50000 epochs   |\n|                  LSTM(CPT)                   |        `1-64-32-2-64`        |   7.29442   |  5.81410  |   62786   |         1.48 hour         |\n|                   GRU(CPT)                   |                              |   7.48624   |  5.89073  |           |                           |\n|                 DG-GCLSTM-V1                 |      `1-1-1-64-32-2-64`      |   6.97208   |  5.79428  |   62789   |         4.55 hour         |\n|                 IG-GCLSTM-V1                 |      `1-1-1-64-32-2-64`      |   7.19536   |  5.87106  |   62789   |         4.40 hour         |\n|                 CG-GCLSTM-V1                 |      `1-1-1-64-32-2-64`      |   6.97782   |  5.94440  |   62789   |         0.93 hour         |\n|           STMeta-V1 (G/DC)            |      `1-1-1-64-32-2-64`      |   6.67733   |  5.79875  |  130379   |         9.71 hour         |\n|           STMeta-V1 (G/DCI)           |      `1-1-1-64-32-2-64`      |   6.61686   |  5.89154  |  189521   |         8.99 hour         |\n|           STMeta-V1 (G/DCI)           | `2-1-1-64-32-2-64` (batch64) |   6.72327   |  5.83256  |  638911   |  2.04 hour / 2780 epochs  |\n|           STMeta-V2(G/DCI)            |      `1-1-1-64-32-2-64`      |   6.68180   |  5.75596  |  180561   | 22.74 hour / 50000 epochs |\n|           STMeta-V3(G/DCI)            |                              |   6.68701   |  5.95507  |  488447   |                           |\n\n| <font color='#ff0000'>**City: Chengdu**</font> |      Params (Searched)       |  val-rmse   | test-rmse | \\# Params |      Converged Time      |\n| :--------------------------------------------: | :--------------------------: | :---------: | :-------: | :-------: | :----------------------: |\n|                       HM                       |          `0-1-4` ✅           |   7.27949   |  7.35477  |    ---    |           ---            |\n|                    ARIMA(C)                    |             ---              |  12.23546   | 12.52656  |    ---    |           ---            |\n|                  ARIMA (CPT)                   |             ---              |   9.56320   |  9.89791  |    ---    |           ---            |\n|            SARIMA (3,0,1)(1,0,0,24)            |                              |   9.26459   |  9.33176  |           |                          |\n|           SARIMA (3,0,1)(1,0,0,128)            |                              |             |           |           |                          |\n|                    XGBoost                     |       `9-14-4-20-2` ✅        |   7.68706   |  7.73836  |    ---    |           ---            |\n|                      GBRT                      |       `12-7-2-50-5 `✅        |   7.54566   |  7.58831  |    ---    |           ---            |\n|                   ST-ResNet                    |          ✅ `待补充`          | **6.31050** |  7.14638  | `待补充`  |        0.15 hour         |\n|                ST_MGCN (G/DCI)                 |           `待补充`           |   6.55319   |  7.03217  |  248985   | 1.60 hour /  422 epochs  |\n|                  DCRNN(G/D C)                  |                              |  10.33887   | 11.50550  |   50368   | 2.52 hour / 10000 epochs |\n|                 DCRNN(G/C CPT)                 |             ---              |   6.70479   |  7.21055  |  149056   |        0.87 hour         |\n|                    LSTM(C)                     |        `1-64-32-2-64`        |   9.12553   | 10.11386  |   28992   | 3.61 hour / 50000 epochs |\n|                   LSTM(CPT)                    |        `1-64-32-2-64`        |   6.46543   |  7.04884  |   62786   |        1.27 hour         |\n|                   GRU (CPT)                    |                              |   6.53480   |  7.04935  |   50111   | 4.49 hour / 6051 epochs  |\n|                  DG-GCLSTM-V1                  |      `1-1-1-64-32-2-64`      |   6.56428   |  7.04343  |   62789   |        7.39 hour         |\n|                  IG-GCLSTM-V1                  |      `1-1-1-64-32-2-64`      |   6.49908   |  7.02130  |   62789   |        2.70 hour         |\n|                  CG-GCLSTM-V1                  |      `1-1-1-64-32-2-64`      |   6.77519   |  7.27282  |   62789   |        2.31 hour         |\n|            STMeta-V1 (G/DC)             |      `1-1-1-64-32-2-64`      |   6.54396   |  7.10324  |  130379   |        4.16 hour         |\n|            STMeta-V1 (G/DCI)            |      `1-1-1-64-32-2-64`      |   6.63979   |  7.06246  |  189521   |        1.66 hour         |\n|            STMeta-V1 (G/DCI)            | `2-1-1-64-32-2-64` (batch64) |   6.55178   |  7.0402   |  638911   | 1.43 hour / 2017 epochs  |\n|            STMeta-V2 (G/DCI)            |                              |   6.59178   |  7.09710  |  180561   |        12.92 hour        |\n|            STMeta-V3 (G/DCI)            |                              |   6.64110   |  7.04358  |  488447   |                          |\n\n## Results on Metro\n\n| <font color='#ff0000'>**City: Chongqing**</font> |       Params       |   val-rmse   |  test-rmse   | \\# Params |      Converged Time      |\n| :----------------------------------------------: | :----------------: | :----------: | :----------: | :-------: | :----------------------: |\n|                        HM                        |     `0-1-4` ✅      |  208.73630   |  120.30723   |    ---    |           ---            |\n|                     ARIMA(C)                     |        ---         |  547.82632   |  578.18563   |    ---    |           ---            |\n|                    ARIMA(PT)                     |        ---         |  341.55182   |  341.55182   |    ---    |           ---            |\n|                    ARIMA(CPT)                    |        ---         |  721.23909   |  680.03948   |    ---    |           ---            |\n|              SARIMA(3,0,1 1,0,0,24)              |                    |   544.3288   |  564.30905   |           |                          |\n|                     XGBoost                      |  `9-14-2-200-5` ✅  |  115.05053   |  117.05069   |    ---    |           ---            |\n|                       GBRT                       | `12-10-4-200-5 `✅  |  118.89574   |  113.92276   |    ---    |           ---            |\n|                 ST_MGCN (G/DCI)                  |      `待补充`      |  105.19451   |  118.86668   |  248985   |  40.38 hour 2189 epochs  |\n|                   DCRNN(G/D C)                   |        ---         |   93.04695   |  122.31121   |           |                          |\n|                  DCRNN(G/C CPT)                  |        ---         |  177.18455   |  118.75352   |  371008   |  2.97 hour / 431 epochs  |\n|                     LSTM(C)                      |   `1-64-32-2-64`   |  172.48973   |  196.175732  |   28992   | 5.72 hour / 20000 epochs |\n|                    LSTM(CPT)                     |   `1-64-32-2-64`   |  128.78950   |   97.50337   |   62786   |        13.46 hour        |\n|                     GRU(CPT)                     |                    |  113.36167   |   89.47513   |           |                          |\n|                   DG-GCLSTM-V1                   | `1-1-1-64-32-2-64` |  113.54371   |  100.45433   |   62789   |        15.55 hour        |\n|                   IG-GCLSTM-V1                   | `1-1-1-64-32-2-64` |  116.70645   |   93.73172   |   62789   |        15.36 hour        |\n|                   CG-GCLSTM-V1                   | `1-1-1-64-32-2-64` |  106.80433   |   99.53486   |   62789   |        15.21 hour        |\n|             STMeta-V1 (G/DC)              | `1-1-1-64-32-2-64` |   86.27438   | **90.83853** |  130379   |        29.63 hour        |\n|             STMeta-V1 (G/DCI)             | `1-1-1-64-32-2-64` | **84.69295** |   92.74990   |  189521   |        38.91 hour        |\n|             STMeta-V1 (G/DCI)             | `2-1-1-64-32-2-64` |   98.12365   |  102.22088   |  638911   | 23.91 hour / 6887 epochs |\n|             STMeta-V2 (G/DCI)             |                    |   95.93984   |   98.86152   |  180561   |        30.64 hour        |\n|             STMeta-V3(G/DCI)              |                    |   93.19236   |   101.7806   |  488447   |                          |\n\n| <font color='#ff0000'>**City: Shanghai**</font> |       Params       |   val-rmse    |   test-rmse   | \\# Params |      Converged Time       |\n| :---------------------------------------------: | :----------------: | :-----------: | :-----------: | :-------: | :-----------------------: |\n|                       HM                        |     `0-1-4` ✅      |   114.48651   |   197.97092   |    ---    |            ---            |\n|                    ARIMA(C)                     |        ---         |   831.0219    |   792.1597    |    ---    |            ---            |\n|                    ARIMA(PT)                    |        ---         |   567.51166   |   546.38855   |    ---    |            ---            |\n|                   ARIMA(CPT)                    |        ---         |   660.60764   |   666.52287   |    ---    |            ---            |\n|           SARIMA((3,0,1), (1,0,0,24))           |                    |   820.3219    |   802.2262    |           |                           |\n|          SARIMA((3,0,1), (1,0,0,168))           |                    |      ---      |   801.2712    |           |                           |\n|                     XGBoost                     |   `3-7-0-50-5` ✅   | **103.81190** |   185.00447   |    ---    |            ---            |\n|                      GBRT                       | `12-10-0-100-2 `✅  |   105.85584   |   186.74502   |    ---    |            ---            |\n|                 ST_MGCN (G/DCI)                 |      `待补充`      |   119.74849   |   181.55171   |  248985   |  3.35 hour / 694 epochs   |\n|                  DCRNN(G/D C)                   |        ---         |   293.57379   |   326.97357   |   50368   | 4.17 hour / 20000 epochs  |\n|                 DCRNN(G/C CPT)                  |        ---         |   137.01097   |   195.22157   |  371008   |  1.43 hour / 770 epochs   |\n|                     LSTM(C)                     |   `1-64-32-2-64`   |   349.61013   |   368.8468    |   28992   | 2.61 hour / 20000 epochs  |\n|                    LSTM(CPT)                    |   `1-64-32-2-64`   |   131.92126   |   182.28558   |   62786   |         5.01 hour         |\n|                    GRU(CPT)                     |                    |   136.16528   |   180.65565   |           | 5.89 hour / 20000 epochs  |\n|                  DG-GCLSTM-V1                   | `1-1-1-64-32-2-64` |   137.98910   |   171.62920   |   62789   |         6.11 hour         |\n|                  IG-GCLSTM-V1                   | `1-1-1-64-32-2-64` |   136.83477   |   168.94954   |   62789   |         5.71 hour         |\n|                  CG-GCLSTM-V1                   | `1-1-1-64-32-2-64` |   141.37688   |   189.21147   |   62789   |         2.34 hour         |\n|             STMeta-V1 (G/DC)             | `1-1-1-64-32-2-64` |   133.77488   |   162.10970   |  130379   |         9.70 hour         |\n|            STMeta-V1 (G/DCI)             | `1-1-1-64-32-2-64` |   131.04696   | **151.11746** |  189521   |        11.96 hour         |\n|            STMeta-V1 (G/DCI)             | `2-1-1-64-32-2-64` |   131.71449   |   166.59117   |  638911   |  3.85 hour / 4904 epochs  |\n|            STMeta-V2 (G/DCI)             | `1-1-1-64-32-2-64` |   131.95754   |   158.21953   |  180561   | 13.27 hour / 20000 epochs |\n|            STMeta-V3 (G/DCI)             |                    |   128.10709   |   156.58867   |  488447   |    12.45 hour / 11010     |\n\nMetro 上的period、trend特征性更强，所以仅使用closeness效果很差\n\n#### Parameter Search on Metro\n\n| **Shanghai**  |  gcn_k=1  |  gcn_k=2  |  gcn_k=3  |\n| :-----------: | :-------: | :-------: | :-------: |\n| batch_size=16 | 146.00493 | 165.69554 | 170.96187 |\n| batch_size=32 | 159.56485 | 156.99149 | 183.77316 |\n| batch_size=64 | 171.51431 | 164.5659  | 192.27948 |\n\n## Results on Charge-Station\n\n| <font color='#ff0000'>**City: Beijing**</font> |               Params               |  val-rmse   |  test-rmse   | \\# Params |      Converged Time       |\n| :--------------------------------------------: | :--------------------------------: | :---------: | :----------: | :-------: | :-----------------------: |\n|                       HM                       |             `2-0-2` ✅              |   0.99617   |   1.01610    |    ---    |            ---            |\n|                    ARIMA(C)                    |                                    |   0.96335   |   0.98236    |    ---    |            ---            |\n|                   ARIMA(CPT)                   |                                    |   1.49936   |   1.56517    |    ---    |            ---            |\n|                     SARIMA                     |                                    |   0.83333   |   0.87392    |           |                           |\n|                    XGBoost                     |          `12-7-0-20-2` ✅           |   0.79800   |   0.83381    |    ---    |            ---            |\n|                      GBRT                      |         `12-10-0-100-2 `✅          |   0.79771   |   0.82814    |    ---    |            ---            |\n|                 ST_MGCN (G/DC)                 |              `待补充`              |   0.59853   |   0.82714    |  166025   |   1.57 hour  253 epochs   |\n|                  DCRNN(G/D C)                  |                                    |   0.70646   |   0.98871    |   50368   | 7.20 hour / 10000 epochs  |\n|                 DCRNN(G/C CPT)                 |                                    |   0.62888   |   0.84680    |   50368   |         0.35 hour         |\n|                    LSTM(C)                     |           `1-64-32-2-64`           |   1.17335   |   1.58560    |   28992   |  1.04 hour / 441 epochs   |\n|                   LSTM(CPT)                    |           `1-64-32-2-64`           |   0.59935   |   0.83322    |   62786   |         9.68 hour         |\n|                    GRU(CPT)                    |                                    |   0.61381   |   0.84800    |           |                           |\n|                  DG-GCLSTM-V1                  |         `1-1-1-64-32-2-64`         |   0.59233   |   0.83743    |   62789   |        12.70 hour         |\n|                  CG-GCLSTM-V1                  |         `1-1-1-64-32-2-64`         | **0.57863** |   0.82140    |   62789   |        17.43 hour         |\n|            STMeta-V1 (G/DC)             |         `1-1-1-64-32-2-64`         |   0.57868   | **0.815518** |  130379   | 26.27 hour / 20000 epochs |\n|            STMeta-V1 (G/DC)             | `2-1-1-64-32-2-64` (batch_size 64) |   0.58788   |   0.83315    |  638911   |                           |\n|            STMeta-V2 (G/DC)             |                                    |   0.58936   |   0.82144    |  129867   | 16.48 hour / 16491 epochs |\n|            STMeta-V3 (G/DC)             |                                    |   0.56721   |   0.81541    |  488447   |                           |\n\n"
  },
  {
    "path": "docs/_sources/md_file/static/amulti_gclstm.md.txt",
    "content": "## Different versions of AMulti-GCLSTM\r\n\r\n|   Version Name   | Temporal Feature Process | Temporal Merge Method | Multi-Graph Merge Method | Parameter Complexity |\r\n| :--------------: | :----------------------: | :-------------------: | :----------------------: | :------------------: |\r\n| AMulti-GCLSTM-V1 |          GCLSTM          |          GAL          |           GAL            |                      |\r\n| AMulti-GCLSTM-V2 |          GCLSTM          |     Concat+Dense      |           GAL            |                      |\r\n| AMulti-GCLSTM-V3 |           RGAL           |          GAL          |           GAL            |                      |\r\n\r\n"
  },
  {
    "path": "docs/_sources/md_file/static/current_supported_models.md.txt",
    "content": "## Currently Supported Models\n\n### AGCRN (Adaptive Graph Convolutional Recurrent Network)\n\nAGCRN is a deep nerual network for traffic prediction consisting of two adaptive module and recurrent networks.\n\n- Reference Paper:\n  - [Bai, L., Yao, L., Li, C., Wang, X., & Wang, C. (2020). Adaptive graph convolutional recurrent network for traffic forecasting.](https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf)\n- Reference Implementation:\n  - [Github repository (LeiBAI)](https://github.com/LeiBAI/AGCRN)\n\n###  ARIMA (Autoregressive Integrated Moving Average)\n\nARIMA is a widely used classical statistical model on time series prediction.\n\n- Reference Paper:\n\n  + [Williams, B. M., & Hoel, L. A. (2003). Modeling and forecasting vehicular traffic flow as a seasonal ARIMA process: Theoretical basis and empirical results](https://www3.nd.edu/~busiforc/handouts/ARIMA%20Engineering%20Article.pdf)\n- Reference Package: `pandas`, `statsmodels`\n\n### ASTGCN (Attenion Based Spatial-temporal Graph Convolutional Networks)\n\nASTGCN is a deep neural network for traffic flow forecasting. It models temporal-dependencies from three perspectives using attetion mechanism. And it models spatial-dependencies employing graph convolutions.\n\n- Reference Paper:\n  - [Guo, S., Lin, Y., Feng, N., Song, C., & Wan, H. (2019, July). Attention based spatial-temporal graph convolutional networks for traffic flow forecasting.](https://ojs.aaai.org/index.php/AAAI/article/view/3881)\n- Reference Implementation:\n  - [Github repository (guoshnBJTU)](https://github.com/guoshnBJTU/ASTGCN-r-pytorch)\n\n###  DCRNN (Diffusion Convolutional Recurrent Neural Network)\n\nDCRNN is a deep learning framework for traffic forecasting that incorporates both spatial and temporal dependency in the traffic flow. It captures the spatial dependency using bidirectional random walks on the graph, and the temporal dependency using the encoder-decoder architecture with scheduled sampling.\n\n- Reference Paper:\n\n  + [Li, Y., Yu, R., Shahabi, C., & Liu, Y. (2017). Diffusion convolutional recurrent neural network: Data-driven traffic forecasting](https://arxiv.org/abs/1707.01926)\n- Reference Implementation: \n  + [A TensorFlow implementation of Diffusion Convolutional Recurrent Neural Network (liyaguang)](https://github.com/liyaguang/DCRNN)\n\n###  DeepST (Deep learning-based prediction model for Spatial-Temporal data)\n\nDeepST is composed of three components: 1) temporal dependent instances: describing temporal closeness, period and seasonal trend; 2) convolutional neural networks: capturing near and far spatial dependencies; 3) early and late fusions: fusing similar and different domains' data.\n\n- Reference Paper:\n\n  + [Zhang, J., Zheng, Y., Qi, D., Li, R., & Yi, X. (2016, October). DNN-based prediction model for spatio-temporal data](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf)\n\n###  GeoMAN (Multi-level Attention Networks for Geo-sensory Time Series Prediction)\n\nGeoMAN consists of two major parts: 1) A multi-level attention mechanism (including both local and global  spatial attentions in encoder and temporal attention in decoder) to model the dynamic spatio-temporal  dependencies; 2) A general fusion module to incorporate the external factors from different domains (e.g.,  meteorology, time of day and land use).\n\n- Reference Paper:\n\n  + [Liang, Y., Ke, S., Zhang, J., Yi, X., & Zheng, Y. (2018, July). GeoMAN: Multi-level Attention Networks for Geo-sensory Time Series Prediction](https://www.ijcai.org/proceedings/2018/0476.pdf)\n- Reference Implementation:\n  + [An easy implement of GeoMAN using TensorFlow (yoshall & CastleLiang)](https://github.com/yoshall/GeoMAN)\n\n### GMAN (Graph Multi-Attention Network)\n\nGMAN is a deep nerual network for traffic prediction adopting encoder-decoder architecture. Both encode and decoder consist of multiple spatio-temporal attention blocks to model spatio-temporal dependencies.\n\n- Reference Paper:\n  - [Zheng, C., Fan, X., Wang, C., & Qi, J. (2020, April). Gman: A graph multi-attention network for traffic prediction.](https://ojs.aaai.org/index.php/AAAI/article/view/5477)\n- Reference Implementation:\n  - [implementation of Graph Multi-Attention Network](https://github.com/zhengchuanpan/GMAN)\n\n### GraphWaveNet\n\nGraphWaveNet is an end-to-end novel graph neural network. It captures spatial dependencies through a self-adptive adjacency matrix. And it captures temporal dependencies through convolutions.\n\n- Reference Paper:\n  - [Wu, Z., Pan, S., Long, G., Jiang, J., & Zhang, C. (2019). Graph wavenet for deep spatial-temporal graph modeling.](https://www.ijcai.org/proceedings/2019/0264.pdf)\n- Reference Implementation:\n  - [Github repository (nnzhan)](https://github.com/nnzhan/Graph-WaveNet)\n\n###  HM (Historical Mean)\n\nHM is a constant model and always forecasts the sample mean of the historical data.\n\n###  HMM (Hidden Markov Model)\n\nHidden Markov Model is a statistical Markov model in which the system being modeled is assumed to be a Markov process with hidden states. It is often used in temporal pattern recognition.\n\n- Reference Paper:\n\n  + [Chen, Z., Wen, J., & Geng, Y. (2016, November). Predicting future traffic using hidden markov models](https://ieeexplore.ieee.org/abstract/document/7785328)\n- Reference Package: `hmmlearn`\n\n### STGCN (Spatio-temporal Graph Convolutional Networks)\n\nSTGCN is a deep learning framework for traffic forecasting with complete convolutional structures.\n\n- Reference Paper:\n  - [Yu, B., Yin, H., & Zhu, Z. (2017). Spatio-temporal graph convolutional networks: A deep learning framework for traffic forecasting.](https://www.ijcai.org/proceedings/2018/0505.pdf)\n- Reference Implementation:\n  - [Github repository (VeritasYin)](https://github.com/VeritasYin/STGCN_IJCAI-18)\n\n### STMeta\n\nSTMeta is our prediction model, which requires extra graph information as input, and combines Graph Convolution LSTM and Attention mechanism.\n\n- Reference Package: `tensorflow`\n\n### ST-MGCN (Spatiotemporal Multi-graph Convolution Network)\n\nST-MGCN is a deep learning based model which encoded the non-Euclidean correlations among regions using multiple graphs and explicitly captured them using multi-graph convolution.\n\n- Reference Paper:\n\n  + [Geng, X., Li, Y., Wang, L., Zhang, L., Yang, Q., Ye, J., & Liu, Y. (2019). Spatiotemporal multi-graph convolution network for ride-hailing demand forecasting](https://ieeexplore.ieee.org/abstract/document/7785328)\n- Reference Implementation:\n  + [A PyTorch implementation of the ST-MGCN model  (shawnwang-tech)](https://github.com/shawnwang-tech/ST-MGCN-pytorch)\n\n\n### ST-ResNet\n\nST-ResNet is a deep-learning model with an end-to-end structure based on unique properties of spatio-temporal data making use of convolution and residual units.\n\n- Reference Paper:\n  - [Zhang, J., Zheng, Y., & Qi, D. (2017, February). Deep spatio-temporal residual networks for citywide crowd flows prediction](https://arxiv.org/pdf/1610.00081.pdf)\n- Reference Implementation:\n  - [Github repository (lucktroy)](https://github.com/lucktroy/DeepST/tree/master/scripts/papers/AAAI17)\n\n### STSGCN (Spatial-temporal Synchronous Graph Convolutional Networks)\n\nSTSGCN is a deep learning framework for spatial-temporal network data forecasting. It is able to capture spatial-temporal dependencies through a designed spatial-temporal synchronous modeling mechanism.\n\n- Reference Paper:\n  - [Song, C., Lin, Y., Guo, S., & Wan, H. (2020, April). Spatial-temporal synchronous graph convolutional networks: A new framework for spatial-temporal network data forecasting.](https://ojs.aaai.org/index.php/AAAI/article/view/5438)\n- Reference Implementation:\n  - [Github repository (Davidham3)](https://github.com/Davidham3/STSGCN)\n\n\n### XGBoost\n\nXGBoost is a gradient boosting machine learning algorithm widely used in flow prediction and other machine learning prediction areas.\n\n- Reference Paper:\n  - [Alajali, W., Zhou, W., Wen, S., & Wang, Y. (2018). Intersection Traffic Prediction Using Decision Tree Models](https://www.mdpi.com/2073-8994/10/9/386)\n- Reference Package: `xgboost`\n\n------\n\n<u>[Back To HomePage](../../index.html)</u>\n"
  },
  {
    "path": "docs/_sources/md_file/static/experiment_on_bike.md.txt",
    "content": "## Experiments on bike traffic-flow prediction\n\n- Experiment Setting\n\n  - Dataset\n\n    |        Attributes        | **New York City** |   **Chicago**   |     **DC**      |\n    | :----------------------: | :---------------: | :-------------: | :-------------: |\n    |        Time span         |  2013.03-2017.09  | 2013.06-2017.12 | 2013.07-2017.09 |\n    | Number of riding records |    49,669,470     |   13,826,196    |   13,763,675    |\n    |    Number of stations    |        827        |       586       |       531       |\n\n  Following shows a map-visualization of bike stations in NYC, the latest built stations have deeper color.\n\n  <img src=\"../src/image/Bike_NYC_STMAP.PNG\">\n\n  In the data preprocessing stage, we removed the stations with average daily traffic flow smaller than 1, since predictions for these stations are not significant in real life. The remaining station number are 717, 444 and 378 for NYC, Chicago and DC, respectively.\n\n  - Network parameter setting (STMeta model)\n\n    Following shows the parameters we used and a short explanation of the parameter meaning.  To know more about the parameter, please refer to the API reference.\n\n- Experiment Results\n\n  - CG-GCLSTM Only use correlation graph in the model\n  - DG-GCLSTM Only use distance graph in the model\n  - IG-GCLSTM Only use interaction graph in the model\n\n#### Only closeness feature (will delete in future version)\n\n|                       |   NYC   | Chicago |   DC    |\n| :-------------------: | :-----: | :-----: | :-----: |\n|          HM           | 6.79734 | 4.68078 | 3.66747 |\n|         ARIMA         | 5.60477 | 3.79739 | 3.31826 |\n|          HMM          | 5.42030 | 3.79743 | 3.20889 |\n|        XGBoost        | 5.32069 | 3.75124 | 3.14101 |\n|         LSTM          | 5.13307 | 3.69806 | 3.14331 |\n|       CG-GCLSTM       | 4.64375 | 3.38255 | 2.87655 |\n|       DG-GCLSTM       | 4.67169 | 3.51243 | 2.98404 |\n|       IG-GCLSTM       | 4.77809 | 3.45625 | 2.68370 |\n| ST_MGCN (Multi-Graph) | 4.41732 |         |         |\n|     STMeta     | 4.22640 | 3.02301 | 2.58584 |\n\n#### Latest result\n\n|                       |        NYC         |      Chicago       |         DC         |\n| :-------------------: | :----------------: | :----------------: | :----------------: |\n| HM（params searched） | 3.99224 (C1-P1-T3) | 2.97693 (C1-P1-T2) | 2.63165 (C2-P1-T3) |\n|        XGBoost        |      4.14909       |      3.02530       |      2.73286       |\n|         GBRT          |      3.94348       |      2.85847       |      2.63935       |\n|         LSTM          |      3.78497       |      2.79078       |      2.54752       |\n|       DG-GCLSTM       |      3.63207       |      2.71876       |      2.53863       |\n|       IG-GCLSTM       |      3.78816       |      2.70131       |      2.46214       |\n|       CG-GCLSTM       |      3.69656       |      2.79812       |      2.45815       |\n|   STMeta-V1    |      3.50475       |    **2.65511**     |      2.42582       |\n|   STMeta-V2    |    **3.43870**     |      2.66379       |    **2.41111**     |\n\n- Model training records\n\n  Following data was collected on a Windows PC with *CPU : Interl i7 8700K, Memory: 32 GB, GPU: Nvidia GTX 1080Ti*. \n\n|        ```NYC City```         | SingleGraph-GCLSTM(Average) | STMeta | ST_MGCN  |\n| :---------------------------: | :-------------------------: | :-----------: | :------: |\n| Number of trainable variables |                             |               |  249245  |\n|   Converaged training time    |                             |               | 51 hours |\n\n- Source Code\n\nUse the ```./Experiment/STMeta_Master_Bike.py``` to train the model or view evaluation results. \n\n\n\n<u>[Back To HomePage](../../index.html)</u>"
  },
  {
    "path": "docs/_sources/md_file/static/experiment_on_chargestation.md.txt",
    "content": "## Experiments on Charge-Station demand station\r\n\r\n- Experiment Setting\r\n\r\n  - Dataset\r\n\r\n    |        Attributes        | **Beijing** |\r\n    | :----------------------: | :---------: |\r\n    |        Time span         |             |\r\n    | Number of riding records |             |\r\n    |    Number of stations    |     629     |\r\n\r\n  Following shows a map-visualization of bike stations in NYC, the latest built stations have deeper color.\r\n\r\n  <img src=\"../src/image/Bike_NYC_STMAP.PNG\">\r\n\r\n  In the data preprocessing stage, we removed the stations with average daily traffic flow smaller than 1, since predictions for these stations are not significant in real life. The remaining station number are 717, 444 and 378 for NYC, Chicago and DC, respectively.\r\n\r\n  - Network parameter setting (STMeta model)\r\n\r\n    Following shows the parameters we used and a short explanation of the parameter meaning.  To know more about the parameter, please refer to the API reference.\r\n\r\n    | Parameter  | Value |                  Meaning                   |\r\n    | :--------: | :---: | :----------------------------------------: |\r\n    |    GLL     |   1   |          number of GCLSTM layers           |\r\n    | LSTMUnits  |  64   |       number of hidden units in LSTM       |\r\n    |  GALUnits  |  64   |       number of units used in GAtteL       |\r\n    |  GALHeads  |   2   |       number of multi-head in GAtteL       |\r\n    | DenseUnits |  32   | number of units in penultimate dense layer |\r\n    |     TC     |   0   |           correlation threshold            |\r\n    |     TD     | 1000  |             distance threshold             |\r\n    |     TI     |  500  |           interaction threshold            |\r\n\r\n- Experiment Results\r\n\r\n  - CG-GCLSTM Only use correlation graph in the model\r\n  - DG-GCLSTM Only use distance graph in the model\r\n  - IG-GCLSTM Only use interaction graph in the model\r\n\r\n|                       | Beijing |\r\n| :-------------------: | :-----: |\r\n|          HM           | 1.13594 |\r\n|         ARIMA         | 5.60477 |\r\n|          HMM          | 5.42030 |\r\n|        XGBoost        | 5.32069 |\r\n|         LSTM          | 5.13307 |\r\n|       CG-GCLSTM       | 4.64375 |\r\n|       DG-GCLSTM       | 4.67169 |\r\n|       IG-GCLSTM       | 4.77809 |\r\n| ST_MGCN (Multi-Graph) | 4.41732 |\r\n|     STMeta     | 4.22640 |\r\n\r\nAdd trend and period into feature:\r\n\r\n (C6-P7-T4) means the length of closeness, period and trend are 6, 7, and 4 respective.\r\n\r\nDefault C6-P7-T4\r\n\r\n|               |   NYC   | Chicago |   DC    |\r\n| :-----------: | :-----: | :-----: | :-----: |\r\n| HM (C6-P7-T4) | 4.55474 | 3.28585 | 2.74502 |\r\n| HM (C0-P7-T4) | 4.27844 | 3.18290 | 2.68013 |\r\n|    XGBoost    | 4.14909 | 3.02530 | 2.73286 |\r\n|     GBRT      | 3.94348 | 2.85847 | 2.63935 |\r\n|     LSTM      | 3.92746 | 2.92663 | 2.65197 |\r\n|   DG-GCLSTM   | 3.88572 | 3.00055 | 2.60095 |\r\n|   IG-GCLSTM   | 3.79187 | 2.97707 | 2.58739 |\r\n|   CG-GCLSTM   | 3.77422 | 2.98797 | 2.59339 |\r\n| STMeta | 3.73464 | 2.79475 | 2.47565 |\r\n\r\n- Model training records\r\n\r\n  Following data was collected on a Windows PC with *CPU : Interl i7 8700K, Memory: 32 GB, GPU: Nvidia GTX 1080Ti*. \r\n\r\n|        ```NYC City```         | SingleGraph-GCLSTM(Average) | STMeta | ST_MGCN  |\r\n| :---------------------------: | :-------------------------: | :-----------: | :------: |\r\n| Number of trainable variables |            19749            |     61993     |  249245  |\r\n|   Converaged training time    |           2 hours           |    6 hours    | 51 hours |\r\n\r\n- Source Code\r\n\r\nUse the ```./Experiment/STMeta_Master_Bike.py``` to train the model or view evaluation results. \r\n\r\n\r\n\r\n<u>[Back To HomePage](../../index.html)</u>"
  },
  {
    "path": "docs/_sources/md_file/static/experiment_on_didi.md.txt",
    "content": "## Experiments on DiDi traffic-flow prediction\n\n- Experiment Setting\n\n  - Dataset\n\n    |        Attributes        |    **Xi'an**    |   **Chengdu**   |\n    | :----------------------: | :-------------: | :-------------: |\n    |        Time span         | 2016.10-2016.11 | 2016.10-2016.11 |\n    | Number of riding records |     5922891     |     8439537     |\n    |    Number of stations    |       253       |       256       |\n\n  In the data preprocessing stage, we removed the stations with average daily traffic flow smaller than 1, since predictions for these stations are not significant in real life.\n\n  Network parameter setting (STMeta model)\n\n  - Following shows the parameters we used and a short explanation of the parameter meaning.  To know more about the parameter, please refer to the API reference.\n\n    | Parameter  | Value |                  Meaning                   |\n    | :--------: | :---: | :----------------------------------------: |\n    |    GLL     |   2   |          number of GCLSTM layers           |\n    | LSTMUnits  |  256  |       number of hidden units in LSTM       |\n    |  GALUnits  |  256  |       number of units used in GAtteL       |\n    |  GALHeads  |   2   |       number of multi-head in GAtteL       |\n    | DenseUnits |  32   | number of units in penultimate dense layer |\n    |     TC     |   0   |           correlation threshold            |\n    |     TD     | 1000  |             distance threshold             |\n    |     TI     |  500  |           interaction threshold            |\n    |     lr     | 5e-4  |               learning rate                |\n\n- Experiment Results\n\n  - STMeta uses correlation graph and interaction graph on Xi'an dataset, and uses correlation graph and interaction graph on Chengdu dataset.\n\n|               |  Xi'an   | Chengdu  |\n| :-----------: | :------: | :------: |\n|      HM       | 10.13594 | 14.14511 |\n|     ARIMA     | 10.11464 | 14.53216 |\n|      HMM      | 10.3239  | 15.24771 |\n|    XGBoost    | 8.72033  | 10.73894 |\n|     LSTM      | 9.31375  | 12.05271 |\n| STMeta | 7.20868  | 8.88920  |\n\n#### Adding period and closeness feature into mode\n\n|               |  Xi'an  | Chengdu |\n| :-----------: | :-----: | :-----: |\n|      HM       |         |         |\n|     ARIMA     |         |         |\n|    XGBoost    |         |         |\n|     GBRT      |         |         |\n|     LSTM      | 6.33135 | 6.97385 |\n|   DG-GCLSTM   | 6.50630 | 7.16565 |\n|   IG-GCLSTM   | 6.02866 | 7.20899 |\n|   CG-GCLSTM   | 5.90418 | 7.09994 |\n| STMeta | 5.94591 | 7.26551 |\n\n<u>[Back To HomePage](../../index.html)</u>"
  },
  {
    "path": "docs/_sources/md_file/static/experiment_on_metro.md.txt",
    "content": "## Experiments on subway traffic-flow prediction\r\n\r\n- Experiment Setting\r\n\r\n  - Dataset\r\n\r\n    |        Attributes        |  **Chongqing**  |  **Shanghai**   |\r\n    | :----------------------: | :-------------: | :-------------: |\r\n    |        Time span         | 2016.08-2017.07 | 2017.07-2017.09 |\r\n    | Number of riding records |    409277117    |    403071370    |\r\n    |    Number of stations    |       113       |       288       |\r\n    |     Number of lines      |        5        |       14        |\r\n\r\n  In the data preprocessing stage, we removed the stations with average daily traffic flow smaller than 1, since predictions for these stations are not significant in real life.\r\n\r\n  Network parameter setting (STMeta model)\r\n\r\n  - Following shows the parameters we used and a short explanation of the parameter meaning.  To know more about the parameter, please refer to the API reference.\r\n\r\n    | Parameter  | Value |                  Meaning                   |\r\n    | :--------: | :---: | :----------------------------------------: |\r\n    |    GLL     |   2   |          number of GCLSTM layers           |\r\n    | LSTMUnits  |  256  |       number of hidden units in LSTM       |\r\n    |  GALUnits  |  256  |       number of units used in GAtteL       |\r\n    |  GALHeads  |   2   |       number of multi-head in GAtteL       |\r\n    | DenseUnits |  32   | number of units in penultimate dense layer |\r\n    |     TC     |   0   |           correlation threshold            |\r\n    |     TD     | 1000  |             distance threshold             |\r\n    |     TI     |  500  |           interaction threshold            |\r\n    |     lr     | 3e-4  |               learning rate                |\r\n\r\n- Experiment Results\r\n\r\n  - STMeta uses correlation graph and neighbor graph.\r\n\r\n|               | Chongqing |  Shanghai  |\r\n| :-----------: | :-------: | :--------: |\r\n|      HM       | 786.01197 | 1247.56662 |\r\n|     ARIMA     | 660.28378 | 967.16123  |\r\n|      HMM      | 660.28378 | 614.19177  |\r\n|    XGBoost    | 289.70050 | 416.58629  |\r\n|     LSTM      | 239.97653 | 408.09871  |\r\n| STMeta | 138.81463 | 251.38817  |\r\n\r\n#### Adding period and closeness feature into mode\r\n\r\n|               | Chongqing | Shanghai |\r\n| :-----------: | :-------: | :------: |\r\n|      HM       | 227.0985  |          |\r\n|     ARIMA     |           |          |\r\n|    XGBoost    | 134.9760  |          |\r\n|     GBRT      | 120.3337  |          |\r\n|     LSTM      | 124.6012  |          |\r\n|   DG-GCLSTM   |           |          |\r\n|   IG-GCLSTM   |           |          |\r\n|   CG-GCLSTM   |           |          |\r\n| STMeta |           |          |\r\n\r\n<u>[Back To HomePage](../../index.html)</u>\r\n\r\n"
  },
  {
    "path": "docs/_sources/md_file/static/parameter_search.md.txt",
    "content": "## Purpose\r\n\r\nTo ensure all the experiments, especially the baseline methods, \r\n\r\n"
  },
  {
    "path": "docs/_sources/md_file/static/preprocess_api.md.txt",
    "content": ""
  },
  {
    "path": "docs/_sources/md_file/static/quick_start.md.txt",
    "content": "## Quick Start with HM (Historical Mean)\n\n```python\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import HM\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=1, period_len=1, trend_len=2,\n                                with_lm=False, normalize=False)\n\nhm_obj = HM(c=data_loader.closeness_len, p=data_loader.period_len, t=data_loader.trend_len)\n\nprediction = hm_obj.predict(closeness_feature=data_loader.test_closeness,\n                            period_feature=data_loader.test_period,\n                            trend_feature=data_loader.test_trend)\n\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))\n```\n\n## Quick Start with ARIMA\n\n```python\nimport numpy as np\n\nfrom UCTB.model import ARIMA\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=24, period_len=0, trend_len=0,\n                                with_lm=False, normalize=False)\n\ntest_prediction_collector = []\nfor i in range(data_loader.station_number):\n    try:\n        model_obj = ARIMA(time_sequence=data_loader.train_closeness[:, i, -1, 0],\n                          order=[6, 0, 1], seasonal_order=[0, 0, 0, 0])\n        test_prediction = model_obj.predict(time_sequences=data_loader.test_closeness[:, i, :, 0],\n                                            forecast_step=1)\n    except Exception as e:\n        print('Converge failed with error', e)\n        print('Using last as prediction')\n        test_prediction = data_loader.test_closeness[:, i, -1:, :]\n    test_prediction_collector.append(test_prediction)\n    print('Station', i, 'finished')\n\ntest_rmse = metric.rmse(np.concatenate(test_prediction_collector, axis=-2), data_loader.test_y)\n\nprint('test_rmse', test_rmse)\n```\n\n## Quick Start with HMM\n\n```python\nimport numpy as np\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import HMM\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC',\n                                closeness_len=12, period_len=0, trend_len=0,\n                                with_lm=False, normalize=False)\n\nprediction = []\nfor station_index in range(data_loader.station_number):\n    # train the hmm model\n    try:\n        hmm = HMM(num_components=8, n_iter=100)\n        hmm.fit(data_loader.train_closeness[:, station_index:station_index+1, -1, 0])\n        # predict\n        p = []\n        for time_index in range(data_loader.test_closeness.shape[0]):\n            p.append(hmm.predict(data_loader.test_closeness[time_index, station_index, :, :], length=1))\n    except Exception as e:\n        print('Failed at station', station_index, 'with error', e)\n        # using zero as prediction\n        p = [[[0]] for _ in range(data_loader.test_closeness.shape[0])]\n\n    prediction.append(np.array(p)[:, :, 0])\n    print('Node', station_index, 'finished')\n\nprediction = np.array(prediction).transpose([1, 0, 2])\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))\n```\n\n## Quick Start with XGBoost\n\n```python\nimport numpy as np\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import XGBoost\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=6, period_len=7, trend_len=4,\n                                with_lm=False, normalize=False)\n\nprediction_test = []\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = XGBoost(n_estimators=100, max_depth=3, objective='reg:squarederror')\n\n    model.fit(np.concatenate((data_loader.train_closeness[:, i, :, 0],\n                              data_loader.train_period[:, i, :, 0],\n                              data_loader.train_trend[:, i, :, 0],), axis=-1),\n              data_loader.train_y[:, i, 0])\n\n    p_test = model.predict(np.concatenate((data_loader.test_closeness[:, i, :, 0],\n                                           data_loader.test_period[:, i, :, 0],\n                                           data_loader.test_trend[:, i, :, 0],), axis=-1))\n\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\n\nprediction_test = np.concatenate(prediction_test, axis=-2)\n\nprint('Test RMSE', metric.rmse(prediction_test, data_loader.test_y))\n```\n\n"
  },
  {
    "path": "docs/_sources/md_file/static/stable_test.md.txt",
    "content": "# Stable Test Records\r\n\r\n## DiDi Chengdu\r\n\r\n#### Parameters for building graph\r\n\r\n| Notation |          explanation           | value |\r\n| :------: | :----------------------------: | :---: |\r\n|    TD    |  threshold of distance graph   | 7500m |\r\n|    TI    | threshold of interaction graph |  30   |\r\n|    TC    | threshold of correlation graph | 0.65  |\r\n\r\n#### Parameters for building model\r\n\r\n```json\r\n{\r\n    \"L\": 1,\r\n    \"PT\": 7,\r\n    \"lr\": 5e-05,\r\n    \"TT\": 4,\r\n    \"DenseUnits\": 32,\r\n    \"GALUnits\": 64,\r\n    \"LSTMUnits\": 64,\r\n    \"ESlength\": 500,\r\n    \"patience\": 0.1,\r\n    \"Normalize\": \"True\",\r\n    \"TI\": 30.0,\r\n    \"CT\": 6,\r\n    \"K\": 1,\r\n    \"GALHeads\": 2,\r\n    \"Graph\": \"Distance-Interaction-Correlation\",\r\n    \"GLL\": 1\r\n}\r\n```\r\n\r\n|   实验编号   |   模型版本含义   |         Test-RMSE值          | Test-MAPE |\r\n| :----------: | :--------------: | :--------------------------: | :-------: |\r\n|      1       | STMeta-V2 |           6.98410            |  0.35470  |\r\n|      2       | STMeta-V2 |           7.06971            |  0.36585  |\r\n|      3       | STMeta-V2 |           7.00403            |  0.34867  |\r\n|      4       | STMeta-V2 |           7.04557            |  0.34797  |\r\n|      5       | STMeta-V2 |           7.05717            |  0.36398  |\r\n|      6       | STMeta-V2 |           6.97287            |  0.34735  |\r\n|      7       | STMeta-V2 |           7.03885            |  0.35656  |\r\n|      8       | STMeta-V2 |           7.09894            |  0.36024  |\r\n|      9       | STMeta-V2 |           7.02147            |  0.33930  |\r\n| 均值、标准差 |                  | 均值 7.03252，标准差 0.03865 |           |\r\n|   平均耗时   |                  |          0.5h~1.5h           |           |\r\n\r\n## DiDi Xian\r\n\r\n```json\r\n{\r\n    \"TrainDays\": \"All\",\r\n    \"DenseUnits\": 32,\r\n    \"GALUnits\": 64,\r\n    \"Graph\": \"Distance-Interaction-Correlation\",\r\n    \"CT\": 6,\r\n    \"Train\": \"False\",\r\n    \"Dataset\": \"DiDi\",\r\n    \"GLL\": 1,\r\n    \"TD\": 7500.0,\r\n    \"GALHeads\": 2,\r\n    \"patience\": 0.1,\r\n    \"Epoch\": 10000,\r\n    \"CodeVersion\": \"ST0\",\r\n    \"TT\": 4,\r\n    \"TC\": 0.65,\r\n    \"Device\": \"1\",\r\n    \"L\": 1,\r\n    \"PT\": 7,\r\n    \"ESlength\": 500,\r\n    \"LSTMUnits\": 64,\r\n    \"TI\": 30.0,\r\n    \"Normalize\": \"True\",\r\n    \"City\": \"Xian\",\r\n    \"lr\": 5e-05,\r\n    \"DataRange\": \"All\",\r\n    \"BatchSize\": 128,\r\n    \"K\": 1,\r\n    \"Group\": \"Xian\"\r\n}\r\n```\r\n\r\nSTMeta-V2 多次实验结果，每次实验耗时 0.5h~1.5h\r\n\r\n| 实验编号 | Test-RMSE | Test-MAPE |\r\n| :------: | :-------: | :-------: |\r\n|    1     |  5.80502  |  0.36022  |\r\n|    2     |  5.88970  |  0.35590  |\r\n|    3     |  6.00412  |  0.45126  |\r\n|    4     |  5.93798  |  0.37956  |\r\n|    5     |  6.01064  |  0.39242  |\r\n|    6     |  5.89309  |  0.40803  |\r\n|    7     |  5.84786  |  0.35915  |\r\n|    8     |  5.88188  |  0.36777  |\r\n|    9     |  5.97407  |  0.42393  |\r\n|    10    |  5.80497  |  0.37014  |\r\n\r\n最终结果：Test-RMSE 均值 5.90493，标准差 0.07142\r\n\r\nMetro Shanghai\r\n\r\n```json\r\n{\r\n    \"TrainDays\": \"All\",\r\n    \"patience\": 0.1,\r\n    \"Train\": \"False\",\r\n    \"TT\": 4,\r\n    \"City\": \"ShanghaiV1\",\r\n    \"ESlength\": 500,\r\n    \"K\": 1,\r\n    \"GLL\": 1,\r\n    \"LSTMUnits\": 64,\r\n    \"Normalize\": \"True\",\r\n    \"PT\": 7,\r\n    \"Epoch\": 10000,\r\n    \"GALUnits\": 64,\r\n    \"TI\": 100.0,\r\n    \"lr\": 2e-05,\r\n    \"Dataset\": \"Metro\",\r\n    \"DenseUnits\": 32,\r\n    \"L\": 1,\r\n    \"Group\": \"Shanghai\",\r\n    \"Graph\": \"Distance-line-Correlation\",\r\n    \"DataRange\": \"All\",\r\n    \"GALHeads\": 2,\r\n    \"CodeVersion\": \"ST_Sim_0\",\r\n    \"CT\": 6,\r\n    \"TD\": 5000.0,\r\n    \"TC\": 0.7,\r\n    \"BatchSize\": 128,\r\n    \"Device\": \"1\"\r\n}\r\n```\r\n\r\nSTMeta-V2 多次实验结果，每次实验耗时 6.5h~7.5h\r\n\r\n| 实验编号 | Test-RMSE | Test-MAPE |\r\n| :------: | :-------: | :-------: |\r\n|    1     | 148.88104 |  0.13178  |\r\n|    2     | 149.58350 |  0.14325  |\r\n|    3     | 168.16162 |  0.14498  |\r\n|    4     | 155.88750 |  0.19575  |\r\n|    5     | 155.09171 |  0.18060  |\r\n|    6     | 166.13303 |  0.18040  |\r\n|    7     | 157.08799 |  0.15245  |\r\n\r\n最终结果：Test-RMSE 均值 157.26091，标准差 6.90058\r\n\r\n## ChargeStation Beijing\r\n\r\n```json\r\n{\r\n    \"GALUnits\": 64,\r\n    \"TD\": 1000.0,\r\n    \"TI\": 500.0,\r\n    \"K\": 1,\r\n    \"Train\": \"False\",\r\n    \"CT\": 6,\r\n    \"patience\": 0.1,\r\n    \"ESlength\": 200,\r\n    \"Graph\": \"Distance-Correlation\",\r\n    \"Normalize\": \"True\",\r\n    \"lr\": 2e-05,\r\n    \"Device\": \"0\",\r\n    \"BatchSize\": 128,\r\n    \"LSTMUnits\": 64,\r\n    \"City\": \"Beijing\",\r\n    \"TrainDays\": \"All\",\r\n    \"CodeVersion\": \"ST_Sim1_0\",\r\n    \"TT\": 4,\r\n    \"GALHeads\": 2,\r\n    \"DenseUnits\": 32,\r\n    \"PT\": 7,\r\n    \"Group\": \"Beijing\",\r\n    \"L\": 1,\r\n    \"DataRange\": \"All\",\r\n    \"TC\": 0.1,\r\n    \"Epoch\": 10000,\r\n    \"Dataset\": \"ChargeStation\",\r\n    \"GLL\": 1\r\n}\r\n```\r\n\r\nSTMeta-V2 多次实验结果 (暂时只跑了4次)，每次实验耗时约 10h\r\n\r\n| 实验编号 | Test-RMSE | Test-MAPE |\r\n| :------: | :-------: | :-------: |\r\n|    1     |  0.80954  |  0.22925  |\r\n|    2     |  0.82956  |  0.23242  |\r\n|    3     |  0.82393  |  0.22467  |\r\n|    4     |  0.81360  |  0.22932  |\r\n\r\n最终结果：Test-RMSE 均值 0.81915，标准差 0.0079745\r\n\r\n"
  },
  {
    "path": "docs/_sources/md_file/static/stmeta.md.txt",
    "content": "## Different versions of STMeta\r\n\r\n|   Version Name   | Temporal Feature Process | Temporal Merge Method | Multi-Graph Merge Method | Parameter Complexity |\r\n| :--------------: | :----------------------: | :-------------------: | :----------------------: | :------------------: |\r\n| STMeta-V1 |          GCLSTM          |          GAL          |           GAL            |                      |\r\n| STMeta-V2 |          GCLSTM          |     Concat+Dense      |           GAL            |                      |\r\n| STMeta-V3 |           RGAL           |          GAL          |           GAL            |                      |\r\n\r\n"
  },
  {
    "path": "docs/_sources/md_file/static/transfer_record.md.txt",
    "content": "## Check-In与POI数据处理方法\n\n#### 数据详情\n\n1. 时间范围：Apr 2012 ~ Sept 2013\n\n2. 三个城市的POI数量与check-in数量\n\n   |  城市   | POI数量(计算城市中心为原点、半径为50km的POI数量) | 日均check-in数量(粗略计算所有站点附近1km的checkin数量总和) |\n   | :-----: | :----------------------------------------------: | :--------------------------------------------------------: |\n   |   NYC   |                      71310                       |                  工作日11707，节假日11358                  |\n   | Chicago |                      21949                       |                   工作日2549，节假日2692                   |\n   |   DC    |                      21087                       |                   工作日6049，节假日5450                   |\n\n#### Check-In 特征计算方法\n\n计算 2013-07-15 到 2013-09-15 之间，各个自行车站点附近1km的checkin总数量，按照工作日和节假日分开，即每个站点的特征维度为48，分别为工作日、节假日的24小时checkin\n\n#### POI特征计算方法\n\n一共有428种POI，每个站点统计附近1km出现的POI类型，即每个站点有428维特征\n\n#### 特征相似度方法\n\nCosine Similarity\n\n## 使用Check-In数据进行相似站点的匹配\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|dc|nyc|0.1|1天|5.35244|**5.15155**|8.97297|\n|dc|nyc|0.1|3天|5.35244|**4.83186**|5.60889|\n|dc|nyc|0.1|5天|5.35244|**4.79484**|4.86073|\n|dc|nyc|0.1|7天|5.35244|**4.83927**|5.09481|\n|dc|chicago|0.1|1天|**3.65903**|3.67704|35.02312|\n|dc|chicago|0.1|3天|3.65903|**3.38682**|4.10283|\n|dc|chicago|0.1|5天|3.65903|**3.39081**|3.44701|\n|dc|chicago|0.1|7天|3.65903|**3.16186**|3.36458|\n|chicago|nyc|0.1|1天|7.48254|**6.19588**|8.28328|\n|chicago|nyc|0.1|3天|7.48254|**5.57436**|5.89025|\n|chicago|nyc|0.1|5天|7.48254|**5.54711**|5.64965|\n|chicago|nyc|0.1|7天|7.48254|**5.26407**|6.34057|\n|chicago|dc|0.1|1天|4.32390|**3.87629**|5.78612|\n|chicago|dc|0.1|3天|**4.32390**|4.99620|4.85723|\n|chicago|dc|0.1|5天|4.32390|**3.26380**|3.38408|\n|chicago|dc|0.1|7天|4.32390|**3.15168**|3.27858|\n|nyc|chicago|0.1|1天|5.17356|**4.43069**|12.75022|\n|nyc|chicago|0.1|3天|5.17356|**3.94628**|4.34232|\n|nyc|chicago|0.1|5天|5.17356|**3.93868**|4.52421|\n|nyc|chicago|0.1|7天|5.17356|3.46738|**3.44230**|\n|nyc|dc|0.1|1天|4.11176|**3.58924**|4.46261|\n|nyc|dc|0.1|3天|4.11176|**3.29204**|4.51947|\n|nyc|dc|0.1|5天|4.11176|**3.22782**|3.44588|\n|nyc|dc|0.1|7天|4.11176|**3.09117**|3.17292|\n\n## 使用POI信息进行相似站点匹配\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|dc|nyc|0.1|1天|5.35244|**5.15155**|7.74238|\n|dc|nyc|0.1|3天|5.35244|**4.83186**|5.22502|\n|dc|nyc|0.1|5天|5.35244|**4.79484**|5.14237|\n|dc|nyc|0.1|7天|5.35244|**4.83927**|5.11173|\n|dc|chicago|0.1|1天|**3.65903**|3.67704|42.10733|\n|dc|chicago|0.1|3天|3.65903|**3.38682**|4.01524|\n|dc|chicago|0.1|5天|3.65903|**3.39081**|3.80654|\n|dc|chicago|0.1|7天|3.65903|**3.16186**|3.40228|\n|chicago|nyc|0.1|1天|7.48254|**6.19588**|9.68558|\n|chicago|nyc|0.1|3天|7.48254|**5.57436**|6.06141|\n|chicago|nyc|0.1|5天|7.48254|**5.54711**|5.64207|\n|chicago|nyc|0.1|7天|7.48254|**5.26407**|5.95202|\n|chicago|dc|0.1|1天|4.32390|**3.87629**|7.71124|\n|chicago|dc|0.1|3天|**4.32390**|4.99620|5.20308|\n|chicago|dc|0.1|5天|4.32390|**3.26380**|3.41202|\n|chicago|dc|0.1|7天|4.32390|**3.15168**|3.36520|\n|nyc|chicago|0.1|1天|5.17356|**4.43069**|8.70660|\n|nyc|chicago|0.1|3天|5.17356|**3.94628**|4.68907|\n|nyc|chicago|0.1|5天|5.17356|**3.93868**|4.71885|\n|nyc|chicago|0.1|7天|5.17356|**3.46738**|3.54126|\n|nyc|dc|0.1|1天|4.11176|**3.58924**|4.54878|\n|nyc|dc|0.1|3天|4.11176|**3.29204**|6.51714|\n|nyc|dc|0.1|5天|4.11176|**3.22782**|3.50503|\n|nyc|dc|0.1|7天|4.11176|**3.09117**|3.35844|\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|dc|nyc|0.2|1天|5.35244|**5.15155**|8.01029|\n|dc|nyc|0.2|3天|5.35244|**4.83186**|5.52622|\n|dc|nyc|0.2|5天|5.35244|**4.79484**|5.30417|\n|dc|nyc|0.2|7天|5.35244|**4.83927**|6.07645|\n|dc|nyc|0.2|9天|5.35244|**4.93593**|5.96554|\n|dc|chicago|0.2|1天|**3.65903**|3.67704|46.02469|\n|dc|chicago|0.2|3天|3.65903|**3.38682**|4.22828|\n|dc|chicago|0.2|5天|3.65903|**3.39081**|4.37432|\n|dc|chicago|0.2|7天|3.65903|**3.16186**|3.56052|\n|dc|chicago|0.2|9天|3.65903|**3.12768**|3.39922|\n|nyc|chicago|0.2|1天|5.17356|**4.43069**|11.41116|\n|nyc|chicago|0.2|3天|5.17356|**3.94628**|4.55703|\n|nyc|chicago|0.2|5天|5.17356|**3.93868**|4.31149|\n|nyc|chicago|0.2|7天|5.17356|**3.46738**|3.59811|\n|nyc|chicago|0.2|9天|5.17356|**3.37643**|3.48236|\n|nyc|dc|0.2|1天|4.11176|**3.58924**|5.95973|\n|nyc|dc|0.2|3天|4.11176|**3.29204**|5.09110|\n|nyc|dc|0.2|5天|4.11176|**3.22782**|4.01670|\n|nyc|dc|0.2|7天|4.11176|**3.09117**|3.34005|\n|nyc|dc|0.2|9天|4.11176|**3.02813**|3.31671|\n|chicago|nyc|0.2|1天|7.48254|**6.19588**|9.18276|\n|chicago|nyc|0.2|3天|7.48254|**5.57436**|5.94807|\n|chicago|nyc|0.2|5天|7.48254|**5.54711**|6.02357|\n|chicago|nyc|0.2|7天|7.48254|**5.26407**|6.02906|\n|chicago|nyc|0.2|9天|7.48254|**5.21905**|5.96555|\n|chicago|dc|0.2|1天|4.32390|**3.87629**|5.75511|\n|chicago|dc|0.2|3天|**4.32390**|4.99620|7.56254|\n|chicago|dc|0.2|5天|4.32390|**3.26380**|4.44143|\n|chicago|dc|0.2|7天|4.32390|**3.15168**|3.65643|\n|chicago|dc|0.2|9天|4.32390|**3.13602**|3.25901|\n\n## 分析Transfer效果在城市中的分布\n\n绿色的点表示transfer效果好于finetune，红色代表差于finetune\n\n#### Target City DC\n\n左侧为 Chicago=>DC，Overall result ：Finetune 3.13602，Transfer 3.25901\n\n右侧为 NYC=>DC，Overall result ：Finetune 3.02813，Transfer 3.31671\n\n![1567254312266](..\\src\\image\\transfer_dc.png)\n\n#### Target City NYC\n\n左侧为 DC => NYC，Overall result ：Finetune 4.93593，Transfer 5.96554\n\n右侧为 Chicago =>NYC，Overall result ：Finetune 5.21905，Transfer 5.96555\n\n![1567253682671](..\\src\\image\\transfer_nyc.png)\n\n#### Target City Chicago\n\n左侧为 NYC=>Chicago，Overall result ：Finetune 3.37643，Transfer 3.48236\n\n右侧为 DC=>Chicago，Overall result ：Finetune 3.12768，Transfer 3.39922\n\n![1567255183794](..\\src\\image\\transfer_chicago.png)"
  },
  {
    "path": "docs/_sources/md_file/static/tutorial.md.txt",
    "content": "\n## Tutorial\n\n#### Use datasets from UCTB\n\nUCTB is designed for urban computing in various scenarios. Currently, It presets a public dataset about bikesharing. This dataset was collected from U.S. open data portals, including 49 million, 13 million, and 14 million historical flow records in [New York City](https://www.citibikenyc.com/system-data) (``NYC``), [Chicago](https://www.divvybikes.com/system-data) (``Chicago``) and [Washington, D.C](https://www.capitalbikeshare.com/system-data) (``DC``), respectively. Each record contains the start station, start time, stop station, stop time, etc. We predict the number of bikesharing demands in each station (i.e., the number of bike borrowers).\n\nIn the future version, we consider releasing more datasets covering other applications such as ridesharing, metro traffic flow, and electrical charging station usage. **If you are interested in this project, making a contribution to the dataset is strongly welcomed :)** \n\nTo help better accuse dataset, UCTB provides data loader APIs ``UCTB.dataset.data_loader``, which can be used to preprocess data, including data division, normalization, and extract temporal and spatial knowledge. \n\nIn the following tutorial, we illustrate how to use ``UCTB.dataset.data_loader`` APIs to inspect the bikesharing dataset.\n\n\n```python\nfrom UCTB.dataset.data_loader import NodeTrafficLoader\n```\n\nWe use 10% (``data_range=0.1``) of the bike data in New York as an example. Firstly, let's initialize a ``NodeTrafficLoader`` object:\n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC')\n```\n\nTake a look at the necessary information about the dataset:\n\n\n```python\n# Traffic data \nprint('Data time range', data_loader.dataset.time_range)\nprint('Traffic data shape:', data_loader.traffic_data.shape)\n# The first dimension of data_loader.traffic_data is the length of time-sequence.\n# The second dimension is the number of stations.\nprint('Time fitness:', data_loader.dataset.time_fitness, 'minutes')\nprint('Time sequence length:', data_loader.traffic_data.shape[0])\nprint('Number of stations:', data_loader.traffic_data.shape[1])\n```\n\n    Data time range ['2013-07-01', '2017-09-30']\n    Traffic data shape: (3724, 717)\n    Time fitness: 60 minutes\n    Time sequence length: 3724\n    Number of stations: 717\n\n\nVisualize the distribution of the traffic data:\n\n\n```python\nimport matplotlib.pyplot as plt\nplt.plot(data_loader.traffic_data[:, 0])\nplt.show()\n```\n\n\n![png](../src/image/toturial_p1_dataplot.png)\n\n\n#### Build your own datasets\n\nTo make loader APIs compatible with your own data, you can store it in a ``dict`` variable with formats as follows.\n\n\n```python\n# Let's say ``my_dataset`` is your dataset.\nmy_dataset = {\n    \"TimeRange\": ['YYYY-MM-DD', 'YYYY-MM-DD'],\n    \"TimeFitness\": 60, # Minutes\n    \n    \"Node\": {\n        \"TrafficNode\": np.array, # With shape [time, num-of-node]\n        \"TrafficMonthlyInteraction\": np.array, # With shape [month, num-of-node. num-of-node]\n        \"StationInfo\": {id: [build-time, # Could also be int\n                             lat, lng, name]},\n        \"POI\": []\n    },\n\n    \"Grid\": {\n        \"TrafficGrid\": [],\n        \"GridLatLng\": [],\n        \"POI\": []\n    },\n\n    \"ExternalFeature\": {\n         \"Weather\": [time, weather-feature-dim]\n    }\n}\n```\n\nAnd then save it with package ``pickle`` to a local path ``pkl_file_name``.\n\n\n```python\nimport pickle\npkl_file_name = './my_dataset.pkl'  \nwith open(pkl_file_name, 'wb') as handle:\n    pickle.dump(my_dataset, handle, protocol=pickle.HIGHEST_PROTOCOL)\n```\n\nFinally, you can make uses of your dataset by UCTB's loader APIs:\n\n\n```python\ndata_loader = NodeTrafficLoader(dataset=pkl_file_name)\n```\n\n#### Use build-in models from UCTB\n\n##### Use single temporal feature in regression\n\nUCTB provides many classical and popular spatial-temporal predicting models. These models can be used to either predicting series for a single station or for all stations. You can find the concrete instruction in ``UCTB.model``.\n\nThe following example shows how to use a **Hidden Markov model** to handle a simple time series predicting problem. We will predict the the number of bikesharing demands ``test_y``(i.e., the number of bike borrowers) for a specific station ``target_node``. In this case, the model takes a few recent timesteps in the past as inputs and then predict the future.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom UCTB.model import HMM\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n```\n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=12, period_len=0, trend_len=0,\n                                test_ratio=0.2, normalize=False, with_lm=False, with_tpe=False)\n```\n\nSplit the data into train and test set.\n\n\n```python\ntarget_node = 233\ntrain_x, test_x = data_loader.train_closeness[:, target_node:target_node+1, -1, 0], data_loader.test_closeness[:, target_node, :, :]\ntest_y = data_loader.test_y[:, target_node, 0]\n```\n\nInspect the shape of data.\n\n\n```python\nprint(train_x.shape)\nprint(test_x.shape)\nprint(test_y.shape)\n```\n\n    (2967, 1)\n    (745, 12, 1)\n    (745,)\n\n\nBuild the model.\n\n\n```python\nmodel = HMM(num_components=8, n_iter=50)\n```\n\nNow, we can fit the model to the train dataset.\n\n\n```python\nmodel.fit(x=train_x)\n```\n\n    Status: converged\n\n\nWhen the model is converged, we make predictions on test data.\n\n\n```python\npredictions = []\nfor t in range(test_x.shape[0]):\n    p = np.squeeze(model.predict(x=test_x[t], length=1))\n    predictions.append(p)\n```\n\nWe can evaluate the performance of the model by build-in ``UCTB.evaluation`` APIs.\n\n\n```python\ntest_rmse = metric.rmse(predictions, test_y)\ntest_rmse\n```\n\n\n    3.76137200105079\n\n##### Use multiple temporal features in regression\n\nIn this case, let's take more temporal knowledge about ``target_node`` into account. Specifically, we will concatenate factors, including ``closeness``, ``period``, and ``trend``, and use **XGBoost** as the predicting model.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom UCTB.model import XGBoost\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n```\n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=6, period_len=7, trend_len=4,\n                                test_ratio=0.2, normalize=False, with_lm=False, with_tpe=False)\n```\n\n\n```python\ntarget_node = 233\ntrain_closeness = data_loader.train_closeness[:, target_node, :, 0]\ntrain_period = data_loader.train_period[:, target_node, :, 0]\ntrain_trend = data_loader.train_trend[:, target_node, :, 0]\ntrain_y = data_loader.train_y[:, target_node, 0]\n\ntest_closeness = data_loader.test_closeness[:, target_node, :, 0]\ntest_period = data_loader.test_period[:, target_node, :, 0]\ntest_trend = data_loader.test_trend[:, target_node, :, 0]\ntest_y = data_loader.test_y[:, target_node, 0]\n```\n\n\n```python\ntrain_X = np.concatenate([train_closeness, train_period, train_trend], axis=-1)\ntest_X = np.concatenate([test_closeness, test_period, test_trend], axis=-1)\n```\n\n\n```python\nprint(train_X.shape)\nprint(train_y.shape)\nprint(test_X.shape)\nprint(test_y.shape)\n```\n\n    (2307, 17)\n    (2307,)\n    (745, 17)\n    (745,)\n\n```python\nmodel = XGBoost(n_estimators=100, max_depth=3, objective='reg:linear')\n```\n\n\n```python\nmodel.fit(train_X, train_y)\n```\n\n\n```python\npredictions = model.predict(test_X)\n```\n\n\n```python\nprint('Test RMSE', metric.rmse(predictions, test_y))\n```\n\n    Test RMSE 3.3267457\n\n#### Build your own model using UCTB (Not yet finished)\n\n\n\n------\n\n<u>[Back To HomePage](../index.html)</u>\n\n"
  },
  {
    "path": "docs/_sources/md_file/tutorial.md.txt",
    "content": "\n## Tutorial\n\n#### Use datasets from UCTB\n\nUCTB is designed for urban computing in various scenarios. Currently, It releases [a public dataset repository](https://github.com/uctb/Urban-Dataset) including bike sharing, ride sharing, traffic speed, and pedestrian counting applications. **If you are interested in this project, making a contribution to the dataset is strongly welcomed :)** \n\nTo help better accuse dataset, UCTB provides data loader APIs ``UCTB.dataset.data_loader``, which can be used to preprocess data, including data division, normalization, and extract temporal and spatial knowledge. \n\nIn the following tutorial, we illustrate how to use ``UCTB.dataset.data_loader`` APIs to inspect the bikesharing dataset.\n\n\n```python\nfrom UCTB.dataset.data_loader import NodeTrafficLoader\n```\n\nWe use 10% (``data_range=0.1``) of the bike data in New York as an example. Firstly, let's initialize a ``NodeTrafficLoader`` object:\n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC')\n```\n\nTake a look at the necessary information about the dataset:\n\n\n```python\n# Traffic data \nprint('Data time range', data_loader.dataset.time_range)\nprint('Traffic data shape:', data_loader.traffic_data.shape)\n# The first dimension of data_loader.traffic_data is the length of time-sequence.\n# The second dimension is the number of stations.\nprint('Time fitness:', data_loader.dataset.time_fitness, 'minutes')\nprint('Time sequence length:', data_loader.traffic_data.shape[0])\nprint('Number of stations:', data_loader.traffic_data.shape[1])\n```\n\n    Data time range ['2013-07-01', '2017-09-30']\n    Traffic data shape: (3724, 717)\n    Time fitness: 60 minutes\n    Time sequence length: 3724\n    Number of stations: 717\n\n\nVisualize the distribution of the traffic data:\n\n\n```python\nimport matplotlib.pyplot as plt\nplt.plot(data_loader.traffic_data[:, 0])\nplt.show()\n```\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/toturial_p1_dataplot.png\" alt=\"png\" style=\"zoom:50%;\" />\n\n#### Build your own datasets\n\nTo make loader APIs compatible with your own data, you can store it in a ``dict`` variable with formats as follows.\n\n\n```python\n# Let's say ``my_dataset`` is your dataset.\nmy_dataset = {\n    \"TimeRange\": ['YYYY-MM-DD', 'YYYY-MM-DD'],\n    \"TimeFitness\": 60, # Minutes\n    \n    \"Node\": {\n        \"TrafficNode\": np.array, # With shape [time, num-of-node]\n        \"TrafficMonthlyInteraction\": np.array, # With shape [month, num-of-node. num-of-node]\n        \"StationInfo\": list # elements in it should be [id, build-time, lat, lng, name]\n        \"POI\": []\n    },\n\n    \"Grid\": {\n        \"TrafficGrid\": [],\n        \"GridLatLng\": [],\n        \"POI\": []\n    },\n\n    \"ExternalFeature\": {\n         \"Weather\": [time, weather-feature-dim]\n    }\n}\n```\n\nAnd then save it with package ``pickle`` to a local path ``pkl_file_name``.\n\n\n```python\nimport pickle\npkl_file_name = './my_dataset.pkl'  \nwith open(pkl_file_name, 'wb') as handle:\n    pickle.dump(my_dataset, handle, protocol=pickle.HIGHEST_PROTOCOL)\n```\n\nFinally, you can make uses of your dataset by UCTB's loader APIs:\n\n\n```python\ndata_loader = NodeTrafficLoader(dataset=pkl_file_name)\n```\n\n\nAlso, we provide interface to help build your own dataset, through which we clarify whether a field is necessary or optional when building a UCTB dataset.\n\nTo build a UCTB dataset, it is necessary to provide variables listed as below.\n\n|variable_name|description|\n|:--|:--|\n|time_fitness|The length of the interval between adjacent slots|\n|time_range| the time interval at the beginning and end of the data |\n|traffic_node| the spatio-temporal information |\n|node_satation_info| the basic information of each data collecting node|\n|dataset_name| name of the dataset |\n|city| A variable used to integrate holiday and weather information to traffic data|\n\nThen, use the specified path to save the dataset, otherwise it will be saved in the current run-time path.\n\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago')\n```\n\nAlso, if you want to check what fields are in your datasets, set the argument ``print_dataset`` to ``True``.\n\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago', print_dataset=True)\n```\n\nOutput:\n\n    dataset[TimeRange]:<class 'list'>  (len=2)\n    dataset[TimeFitness]:<class 'int'>\n    dataset[Node]:<class 'dict'>{\n        dataset[Node][TrafficNode]:<class 'numpy.ndarray'>  (shape=(37248, 532))\n        dataset[Node][StationInfo]:<class 'list'>  (len=(532, 5))\n        dataset[Node][TrafficMonthlyInteraction]:<class 'NoneType'>\n    }\n    dataset[Grid]:<class 'dict'>{\n        dataset[Grid][TrafficGrid]:<class 'NoneType'>\n        dataset[Grid][GridLatLng]:<class 'NoneType'>\n    }\n    dataset[ExternalFeature]:<class 'dict'>{\n        dataset[ExternalFeature][Weather]:<class 'list'>  (len=0)\n    }\n    dataset[LenTimeSlots]:<class 'int'>\n\nWhat's more, if you want to integrate additional information of the dataset, just specify the optional argument as bellow.\n\n|variable_name|description|\n|:--|:--|\n|traffic_monthly_interaction| the interactive information among data collecting nodes. |\n|poi| point of interests |\n|traffic_grid| the spatio-temporal information in grid format. |\n|gird_lat_lng| the basic information of each data collecting grid.|\n|Weather| the weather information of each day. |\n\nfor example, specify the argument ``external_feature_weather`` with numpy.array object.\n\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago', \n                print_dataset=True, external_feature_weather=np.zeros([37248,26]))\n```\n\nThe code above use zero matrix to specify the argument ``external_feature_weather``. While in practical application scenario, you should substitute it with real feather matrix. The first dimension of the matrx is the number of time slots, and the second dimension corresponds to the dimension of weather features.\n\n\n#### Use build-in models from UCTB\n\n##### Use single temporal feature in regression\n\nUCTB provides many classical and popular spatial-temporal predicting models. These models can be used to either predicting series for a single station or all stations. You can find the details in [``UCTB.model``](./static/current_supported_models.html).\n\nThe following example shows how to use a **Hidden Markov model (HMM)** to handle a simple time series predicting a problem. We will try to predict the bike demands ``test_y`` of a fixed station ``target_node`` in New York City by checking back the historical demands in recent time slots ``train_closeness``.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom UCTB.model import HMM\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\ntarget_node = 233\n```\n\nWhen initializing the loader, we use past ``12`` time slots (timesteps) of closeness as input, ``1`` timestep in the next as output and set the timesteps of other features ``period_len``, ``period_len`` to zero. \n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=12, period_len=0, trend_len=0,\n                                target_length=1, test_ratio=0.2, \n                                normalize=False, with_lm=False, with_tpe=False)\n```\n\nThe well-loaded data contain all ``717`` stations' data. Therefore it is needed to specify the target station by ``target_station``.\n\n```python\nprint(data_loader.train_closeness.shape)\nprint(data_loader.test_closeness.shape)\nprint(data_loader.test_y.shape)\n```\n\n```python\n(2967, 717, 12, 1)\n(745, 717, 12, 1)\n(745, 717, 1)\n```\n\n\n```python\ntrain_x, test_x = data_loader.train_closeness[:, target_node:target_node+1, -1, 0], data_loader.test_closeness[:, target_node, :, :]\ntest_y = data_loader.test_y[:, target_node, 0]\n```\n\nInspect the shape of data. Here are the all we need for one-station prediction.\n\n\n```python\nprint(train_x.shape)\nprint(test_x.shape)\nprint(test_y.shape)\n```\n\n    (2967, 1)\n    (745, 12, 1)\n    (745,)\n\n\nBuild the HMM model.\n\n\n```python\nmodel = HMM(num_components=8, n_iter=50)\n```\n\nNow, we can fit the model with the train dataset.\n\n\n```python\nmodel.fit(x=train_x)\n```\n\n    Status: converged\n\n\nWhen the model is converged, we make predictions on test data.\n\n\n```python\npredictions = []\nfor t in range(test_x.shape[0]):\n    p = np.squeeze(model.predict(x=test_x[t], length=1))\n    predictions.append(p)\n```\n\nWe can evaluate the performance of the model by build-in ``UCTB.evaluation`` APIs.\n\n\n```python\ntest_rmse = metric.rmse(predictions, test_y)\nprint(test_rmse)\n```\n\n\n    3.76137200105079\n\n##### Use multiple temporal features in regression\n\nIn this case, let's take more temporal knowledge related to ``target_node`` into account. We will concatenate factors including ``closeness``, ``period``, and ``trend``, and use **XGBoost** as the predicting model.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom UCTB.model import XGBoost\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\ntarget_node = 233\n\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=6, period_len=7, trend_len=4,\n                                target_length=1, test_ratio=0.2, \n                                normalize=False, with_lm=False, with_tpe=False)\n\ntrain_closeness = data_loader.train_closeness[:, target_node, :, 0]\ntrain_period = data_loader.train_period[:, target_nodze, :, 0]\ntrain_trend = data_loader.train_trend[:, target_node, :, 0]\ntrain_y = data_loader.train_y[:, target_node, 0]\n\ntest_closeness = data_loader.test_closeness[:, target_node, :, 0]\ntest_period = data_loader.test_period[:, target_node, :, 0]\ntest_trend = data_loader.test_trend[:, target_node, :, 0]\ntest_y = data_loader.test_y[:, target_node, 0]\n\ntrain_X = np.concatenate([train_closeness, train_period, train_trend], axis=-1)\ntest_X = np.concatenate([test_closeness, test_period, test_trend], axis=-1)\n\nprint(train_X.shape)\nprint(train_y.shape)\nprint(test_X.shape)\nprint(test_y.shape)\n\nmodel = XGBoost(n_estimators=100, max_depth=3, objective='reg:linear')\nmodel.fit(train_X, train_y)\npredictions = model.predict(test_X)\nprint('Test RMSE', metric.rmse(predictions, test_y))\n```\n\n    (2307, 17)\n    (2307,)\n    (745, 17)\n    (745,)\n    Test RMSE 3.3267457\n\n#### Build your own model using UCTB\n\nUCTB provides extendable APIs to build your own model. Currently, it can support the running of all the ``1.x`` version of **Tensorflow-based** models. In the following tutorial, we will show you how to takes the least efforts to implement a UCTB model.\n\nCommonly, a new model needs to inherit ``BaseModel`` to acquire the features provided by UCTB, such as batch division, early stopping, etc. The necessary components for a subclass of ``BaseModel`` include:\n\n- ``self.__init__()``. Define the model's parameters related to the architecture. You should call the super class's constructor at first.\n- ``self.build()``. Build the architecture here. You should construct the graph at the beginning of this function and call the super class's ``build()`` function at the end.\n- ``self._input``. The ``dict`` used to record the acceptable inputs of the model, whose keys are the parameter names in ``model.fit()`` and ``model.predict()`` and values are the name of related tensors.\n- ``self._output``. The ``dict`` used to record the outputs of the model. You should fill the required keys ``prediction`` and ``loss`` with the names of tensors in your case.\n- ``self._op``. The ``dict`` used to define all the operations for the model. Basic usage for it is to record the **training operation**, for example, the minimizing loss operation of an optimizer. Use key ``train_op`` to record it.\n\nFor more examples, you can refer to the implementations of build-in models in [``UCTB.model``](../UCTB.model.html#uctb-model-package).\n\n\n```python\nfrom UCTB.model_unit import BaseModel\n\nclass MyModel(BaseModel):\n    def __init__(self,\n                 \n                 code_version='0',\n                 model_dir='my_model',\n                 gpu_device='0',\n                ):\n        super(MyModel, self).__init__(code_version=code_version, \n                                      model_dir=model_dir, gpu_device=gpu_device)\n        ...\n        \n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            ...\n            self._input['inputs'] = inputs.name\n            self._input['targets'] = targets.name\n            \n            ...\n            self._output['prediction'] = predictions.name\n            self._output['loss'] = loss.name\n            self._op['train_op'] = train_op.name\n            \n        super(MyModel, self).build(init_vars=init_vars, max_to_keep=5) \n```\n\nNext, in a concrete case, we will realize a **Long short-term memory (LSTM)** model to make the all-station prediction that accepts time series of `717` stations and predict the future of them as a whole. \n\nFor the mechanism of LSTM, you can refer to \n[Gers, F. A., Schmidhuber, J., & Cummins, F. (1999). Learning to forget: Continual prediction with LSTM](https://www.researchgate.net/profile/Felix_Gers/publication/12292425_Learning_to_Forget_Continual_Prediction_with_LSTM/links/5759414608ae9a9c954e84c5/Learning-to-Forget-Continual-Prediction-with-LSTM.pdf).\n\n\n```python\nimport numpy as np\nimport tensorflow as tf\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model_unit import BaseModel\nfrom UCTB.preprocess import SplitData\nfrom UCTB.evaluation import metric\n```\n\n\n```python\nclass LSTM(BaseModel):\n    def __init__(self,\n                 num_stations, \n                 num_layers, \n                 num_units, \n                 input_steps, \n                 input_dim,\n                 output_steps,\n                 output_dim,\n                 code_version='0',\n                 model_dir='my_lstm',\n                 gpu_device='0'):\n        super(LSTM, self).__init__(code_version=code_version, \n                                   model_dir=model_dir, gpu_device=gpu_device)\n        self.num_stations = num_stations\n        self.num_layers = num_layers\n        self.num_units = num_units\n        self.input_steps = input_steps\n        self.input_dim = input_dim\n        self.output_steps = output_steps\n        self.output_dim = output_dim\n        \n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            inputs = tf.placeholder(tf.float32, shape=(None, self.num_stations, \n                                                       self.input_steps, self.input_dim))\n            targets = tf.placeholder(tf.float32, shape=(None, self.num_stations,\n                                                       self.output_steps, self.output_dim))\n            # record the inputs of the model\n            self._input['inputs'] = inputs.name\n            self._input['targets'] = targets.name\n\n            inputs = tf.reshape(inputs, (-1, self.input_steps, self.num_stations*self.input_dim))\n            \n            def get_a_cell(num_units):\n                lstm = tf.nn.rnn_cell.BasicLSTMCell(num_units, state_is_tuple=True)\n                return lstm\n            \n            stacked_cells = tf.contrib.rnn.MultiRNNCell([get_a_cell(self.num_units) for _ in range(self.num_layers)], state_is_tuple=True)\n            outputs, final_state = tf.nn.dynamic_rnn(stacked_cells, inputs, dtype=tf.float32)\n            \n            stacked_outputs = tf.reshape(outputs, shape=(-1, self.num_units*self.input_steps))\n            predictions = tf.layers.dense(stacked_outputs, self.output_steps*self.num_stations*self.output_dim)\n            predictions = tf.reshape(predictions, shape=(-1, self.num_stations, self.output_steps, self.output_dim))\n            \n            loss = tf.sqrt(tf.reduce_mean(tf.square(predictions - targets)))\n            train_op = tf.train.AdamOptimizer().minimize(loss)\n            \n            # record the outputs and the operation of the model\n            self._output['prediction'] = predictions.name\n            self._output['loss'] = loss.name\n            self._op['train_op'] = train_op.name\n        \n        # must call super class' function to build \n        super(LSTM, self).build(init_vars=init_vars, max_to_keep=5) \n```\n\nLoad the dataset by loader and transform them into the formats your model accepts. If the loader APIs are not filled your demands, you can inherit loader and wrapper it according to your desires (see [Quickstart](./quickstart.html) for more details).\n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=6, period_len=0, trend_len=0,\n                                target_length=1, test_ratio=0.2, \n                                normalize=True, with_lm=False, with_tpe=False)\ntrain_y = np.expand_dims(data_loader.train_y, axis=-1)\ntest_y = np.expand_dims(data_loader.test_y, axis=-1)\n```\n\n\n```python\nmodel = LSTM(num_stations=data_loader.station_number, \n             num_layers=2,\n             num_units=512, \n             input_steps=6, \n             input_dim=1, \n             output_steps=1, \n             output_dim=1)\n```\n\n\n```python\nmodel.build()\nprint(model.trainable_vars)  # count the trainble parameters\n```\n\n    6821581\n\nUse your model to training and predicting. ``model.fit()`` method presets lots of useful functions, such as batch division and early stopping. Check them in [``UCTB.model_unit.BaseModel.BaseModel.fit``](../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.fit).\n\n\n```python\nmodel.fit(inputs=data_loader.train_closeness,\n          targets=train_y,\n          max_epoch=10,\n          batch_size=64,\n          sequence_length=data_loader.train_sequence_len,\n          validate_ratio=0.1)\n```\n\n    No model found, start training\n    Running Operation ('train_op',)\n    Epoch 0: train_loss 0.016053785 val_loss 0.01606118\n    Epoch 1: train_loss 0.015499311 val_loss 0.015820855\n    Epoch 2: train_loss 0.015298592 val_loss 0.015657894\n    Epoch 3: train_loss 0.015163456 val_loss 0.015559187\n    Epoch 4: train_loss 0.015066812 val_loss 0.015342651\n    Epoch 5: train_loss 0.015016247 val_loss 0.015287879\n    Epoch 6: train_loss 0.014899823 val_loss 0.015249459\n    Epoch 7: train_loss 0.014773054 val_loss 0.015098239\n    Epoch 8: train_loss 0.014655286 val_loss 0.015097916\n    Epoch 9: train_loss 0.014558283 val_loss 0.015108417\n\n```python\npredictions = model.predict(inputs=data_loader.test_closeness, \n                            sequence_length=data_loader.test_sequence_len)\n```\n\nReverse the normalization by ``data_loader`` and evaluate the results:\n\n\n```python\npredictions = data_loader.normalizer.min_max_denormal(predictions['prediction'])\ntargets = data_loader.normalizer.min_max_denormal(test_y)\nprint('Test result', metric.rmse(prediction=predictions, target=targets))\n```\n\n    Test result 2.9765626570592545\n\nSince we only use a short period of the dataset (``data_range=0.1``) in this toy example, the result looks good compared with the [experiment](./all_results.html#results-on-bike). You can also take a try to test the completed dataset on your model. \n\n#### Build your own graph with STMeta\n\nNext, we will use the Top-K graph as an example to illustrate how to build customized graphs in UCTB. All of the code in this section can be found [here](https://anonymous.4open.science/r/561305b5-e65e-46c6-9371-ae76b85109ee/Experiments/CustomizedDemo/).\n\n##### Top-K graph\n\nFirst of all, the customized graphs used in this section is called Top-K graph. We construct the corresponding adjacent graph by marking the point pair that consist of each point and its nearest K points as 1, and the others are marked as 0. Then, we use the adjacent graph to generate the laplacian matrix for input. The hyperparameter K is designed via ad-hoc heuristics. In this demonstration, we chose 23 as the value of K.\n\n##### Realize TopK graph analysis module\n\nTo adopt customized graphs (***e.g.,*** Top-K) in UCTB, you should first build your own analysis class by inheriting `UCTB.preprocess.GraphGenerator class`.\n\nIt is worth noting that the ultimate goal is to generate the member variables: `self.LM` and `self.AM`, which is the input matrix of the graph. In this phase, we need to make the corresponding analytical implementation according to the type of the custom graph passed in.\n\n ```python\n# \"UCTB/preprocess/topKGraph.py\"\nimport heapq\nimport numpy as np\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n\n# Define the class: topKGraph\nclass topKGraph(GraphGenerator):  # Init NodeTrafficLoader\n\n    def __init__(self,**kwargs):\n\n        super(topKGraph, self).__init__(**kwargs)\n        \n        for graph_name in kwargs['graph'].split('-'):\n\n# As the basic graph is implemented in GraphGenerator, you only need to implement your own graph function instead of the existing one.\n            if graph_name.lower() == 'topk':\n                lat_lng_list = np.array([[float(e1) for e1 in e[2:4]]\n                                         for e in self.dataset.node_station_info])\n                # Handling\n                AM = self.neighbour_adjacent(lat_lng_list[self.traffic_data_index],\n                                        threshold=int(kwargs['threshold_neighbour']))\n                LM = self.adjacent_to_laplacian(AM)\n\n                if self.AM.shape[0] == 0:  # Make AM\n                    self.AM = np.array([AM], dtype=np.float32)\n                else:\n                    self.AM = np.vstack((self.AM, (AM[np.newaxis, :])))\n\n                if self.LM.shape[0] == 0:  # Make LM\n                    self.LM = np.array([LM], dtype=np.float32)\n                else:\n                    self.LM = np.vstack((self.LM, (LM[np.newaxis, :])))\n\n# Implement the details of building the Top-K graph.\n    def neighbour_adjacent(self, lat_lng_list, threshold):\n        adjacent_matrix = np.zeros([len(lat_lng_list), len(lat_lng_list)])\n        for i in range(len(lat_lng_list)):\n            for j in range(len(lat_lng_list)):\n                adjacent_matrix[i][j] = self.haversine(\n                    lat_lng_list[i][0], lat_lng_list[i][1], lat_lng_list[j][0], lat_lng_list[j][1])\n        dis_matrix = adjacent_matrix.astype(np.float32)\n\n        for i in range(len(dis_matrix)):\n            ind = heapq.nlargest(threshold, range(len(dis_matrix[i])), dis_matrix[i].take)\n            dis_matrix[i] = np.array([0 for _ in range(len(dis_matrix[i]))])\n            dis_matrix[i][ind] = 1\n        adjacent_matrix = (adjacent_matrix == 1).astype(np.float32)\n        return adjacent_matrix\n ```\n\n##### Redefine the call statement of the above class\n\n```python\n# \"UCTB/Experiments/CustomizedDemo/STMeta_Obj_topk.py\"\n\n# Import the Class: topKGraph\nfrom topKGraph import topKGraph\n# Call topKGraph to initialize and generate AM and LM\ngraphBuilder = topKGraph(graph=args['graph'],\n                         data_loader=data_loader,\n                         threshold_distance=args['threshold_distance'],\n                         threshold_correlation=args['threshold_correlation'],\n                         threshold_interaction=args['threshold_interaction'],\n                         threshold_neighbour=args['threshold_neighbour'])\n# ......\n```\n\n##### Modify the function call location\n\nAdd the new graph name when fitting model and then execute it for experiments. [code](https://github.com/uctb/UCTB/blob/master/Experiments/CustomizedDemo/Runner_topk.py)\n\n```python\nos.system('python STMeta_Obj_topk.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line-TopK,MergeIndex:12')\n```\n\nWe conduct experiments on `Metro_Shanghai` dataset and use the [STMeta_V1](https://uctb.github.io/UCTB/md_file/all_results.html#stmeta-version) to model both \"Distance-Correlation-Line\" graph and \"Distance-Correlation-Line-TopK\" and the results are following:\n\n| **Metro: Shanghai** |             Graph              | Test-RMSE |\n| :-----------------: | :----------------------------: | :-------: |\n|      STMeta_V1      |   Distance-Correlation-Line    |  153.17   |\n|      STMeta_V1      | Distance-Correlation-Line-TopK |  140.82   |\n\nThe results show that the performance of STMeta_V1 with the graph \"Distance-Correlation-Line-TopK\" is better than \"Distance-Correlation-Line\" model and the RMSE is reduced by about 12.4%, which validates the effectiveness of the topk graph for spatiotemporal modeling STMeta algorithm.\n\n------\n\n<u>[Back To HomePage](../index.html)</u>\n\n"
  },
  {
    "path": "docs/_sources/md_file/uctb_group.md.txt",
    "content": "## About us (UCTB Group)\n\n### PI\n\n**Leye Wang**  \n\n```From Feb 2019, till now.```\n\nAssistant professor @ Key Lab of High Confidence Software Technologies, Department of Computer Science & Technology, Peking University.\n\nEmail: [leyewang@pku.edu.cn](mailto:leyewang@pku.edu.cn) \n\n[Leye Wang's HomePage](https://cs.pku.edu.cn/info/1174/2334.htm)\n\n______\n\n**Longbiao Chen**  \n\n```From March 2022, till now.```\n\nAssociate professor @ Department of Computer Science, Xiamen University, China\n\nEmail: [longbiaochen@xmu.edu.cn](mailto:longbiaochen@xmu.edu.cn) \n\n[Longbiao Chen's HomePage](https://longbiao.crowdsensing.cn/)\n\n### Key Contributors\n\n**Di Chai** (active)\n\n```From Feb 2019, till now.```\n\nPh.D student in computer science and engineering at Hong Kong University of Science and Technology.\n\nEmail: dchai@cse.ust.hk\n\n______\n\n**Liyue Chen** (active)\n\n```From Nov 2019, till now.```\n\nPh.D student in Peking University.\n\nEmail:  chenliyue2019@gmail.com\n\n------\n\n**Jiangyi Fang** (active)\n\n```From April 2022, till now.```\n\nUndergraduate student majored in Automation in Huazhong University of Science and Technology.\n\nEmail:  fangjiangyi2001@gmail.com\n\n------\n\n**Yayao Hong** (active)\n\n```From Sep 2022, till now.```\n\nMaster student in Fujian Key Laboratory of Sensing and Computing for Smart Cities at Xiamen University.\n\nEmail:  hyymmmint@stu.xmu.edu.cn\n\n------\n\n**Tengfei Liu** (active)\n\n```From March 2023, till now.```\n\nUndergraduate student in computer science and technology at China University of Geosciences.\n\nEmail:  tf66366@cug.edu.cn\n\n------\n**Xiuhuai Xie** (active)\n\n```From July 2023, till now.```\n\nPostgraduate student majored in Computer Technology in Xiamen University.\nEmail: trafalgar2001@163.com\n\n### Past Contributors\n\n**Hang Zhu**\n\n```From March 2022, Jul 2023.```\n\nMaster student in Fujian Key Laboratory of Sensing and Computing for Smart Cities at Xiamen University.\n\nEmail:  zhuhang@stu.xmu.edu.cn\n\n------\n\n**Jin Xu**\n\n```From Jul 2019 to Aug 2019.```\n\nUndergraduate student in Peking University majoring in Data Science and Big Data Technology.\n\nEmail: jinxu@pku.edu.cn\n\n______\n\n**Wenjie Yang**\n\n```From Nov 2019 to Aug 2020.```\n\nMaster student in computer science and engineering at Hong Kong University of Science and Technology.\n\nEmail: wjyccs@gmail.com\n\n______\n\n**Xueqiao Xu**\n\n```From Jan 2020 to Jul 2020.```\n\nHe got his bachelor' degree in Peking University majoring in Data Science and Big Data Technology.\n\nEmail:  snowbridge@foxmail.com\n\n------\n\n**Zhenyu Cui**\n\n```From May 2020 to Nov 2020.```\n\nGraduate student in University of Chinese Academy of Sciences, majoring in Computer Vision and Deep Learning.\n\nEmail:  cuizhenyu18@mails.ucas.ac.cn\n"
  },
  {
    "path": "docs/_sources/md_file/urban_dataset.md.txt",
    "content": "# Urban Datasets\n\nUCTB is designed for urban computing in various scenarios. Currently, It releases [a public dataset repository](https://github.com/uctb/Urban-Dataset) including bike sharing, ride sharing, traffic speed, and pedestrian counting applications. **If you are interested in this project, making a contribution to the dataset is strongly welcomed :)**\n\n## Datasets Overview\n\nCurrently, UCTB offers the following datasets in 7 scenarios, with detailed information provided in the table below. We are constantly working to release more datasets in the future.\n\n| **Application**  |        **City**        |     **Time Range**     | **Temporal Granularity** |                                                      **Dataset Link**                                                       |\n|:----------------:|:----------------------:|:----------------------:|:------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|\n|   Bike-sharing   |          NYC           | 2013.07.01-2017.09.30  |        5 minutes         |            [66.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip)             | \n|   Bike-sharing   |        Chicago         | 2013.07.01-2017.09.30  |        5 minutes         |          [30.2M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip)           | \n|   Bike-sharing   |           DC           | 2013.07.01-2017.09.30  |        5 minutes         |             [31.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip)             | \n| Pedestrian Count |       Melbourne        | 2021.01.01-2022.11.01  |        60 minutes        | [1.18M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip) |\n|  Vehicle Speed   |           LA           | 2012.03.01-2012.06.28  |        5 minutes         |            [11.8M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip)             |\n|  Vehicle Speed   |          BAY           | 2017.01.01-2017.07.01  |        5 minutes         |            [27.9M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip)            |\n|   Taxi Demand    |        Chicago         | 2013.01.01-2018.01.01  |        15 minutes        |          [6.1M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|       Bus        |          NYC           | 2022.02.01-2024.01.13  |         60 mins          |             [4.89M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip)             |\n|      Metro       |          NYC           | 2022.02.01-2023.12.21  |         60 mins          |           [11.3M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip)           |\n|   Traffic Flow   |         Luzern         | 2015.01.01-2016.01.01  |          3 mins          |            [21M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Flow/3_minutes/Flow_Luzern.zip)            |\n|   Ride-sharing   |  Chicago (community)   | 2013.01.01-2018.01.01  |         15 mins          |          [6.06](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|   Ride-sharing   | Chicago (census tract) | 2013.01.01-2018.01.01  |         15 mins          |    [10M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip)     |\n|   Ride-sharing   |          NYC           | 2009.01.01-2023.06.01  |          5 mins          |            [36.9M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/5_minutes/Taxi_NYC.zip)             |\n\n## Bike Datasets\nThe bike-sharing datasets are collected from U.S. open data portals including New York City (NYC, https://www.citibikenyc.com/system-data), Chicago (CHI, https://www.divvybikes.com/system-data), and DC (https://www.capitalbikeshare.com/system-data). The dataset time span for all three cities is more than four years. The total number of historical flow records is around 49 million, 13 million, and 14 million in NYC, Chicago, and DC, respectively, and each record contains the start station, start time, stop station, stop time, etc.\n\nThe following shows the map visualization of bike stations in NYC, Chicago, and DC.\n\n<div style=\"display: flex;\">\n  <img src=\"https://camo.githubusercontent.com/eb6a2130ac83330fa6e79276f561c3966c79b7cc90b6cba5b79980127faaa316/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f4e59432e6a7067\" alt=\"图片1\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/9bb00c6ffb052701433ec46dfe52e96365014a2aa3eab825dc4f52e319ff3d1d/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f4368696361676f2e6a7067\" alt=\"图片2\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/a57455f9f9ccba9ed12ec57b3d5d805d75f4577278c824834ea429dc844cf976/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f44432e6a7067\" alt=\"图片3\" style=\"flex: 1; max-width: 300px; height: auto;\">\n</div>\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Bike/\n\n## Bus Datasets\nThe bus datasets are collected from DATA.NY.GOV: MTA Bus Hourly Ridership. This dataset is provided by the Metropolitan Transportation Authority and is available for public download. It offers bus ridership estimates on an hourly basis by bus route. Data collection started from February 2022 and has been regularly updated. The Bus_NYC dataset includes data up to January 13, 2024. The latest version can be accessed on the website mentioned above. The station info data is downloaded from NYU | Faculty Digital Archive: New York City Bus Routes, Dec 2019. It does not encompass all bus routes. So we discarded the traffic data for bus routes where station information was not found, ultimately retaining 226 bus routes.\nFollowing shows the map-visualization of Bus_NYC datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Bus.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Bus\n\n## Speed Datasets\nThe two traffic speed datasets are widely used in STTP research: METR-LA and PEMS-BAY from Los Angeles (LA) County and Bay Area, respectively. In METR-LA, 207 sensors record highway vehicles’ speeds for four months; In PEMS-BAY, there are 325 sensors for six months. Each sensor can be seen as a station.\n\nFollowing shows the map-visualization of METR-LA and PEMS-BAY.\n<div style=\"display: flex;\">\n  <img src=\"https://camo.githubusercontent.com/7beb63775a5bcd043923b5b749896af2d10358bc30e2c974f07a882e5b70b20a/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f4d4554525f4c412e706e67\" alt=\"图片1\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/091bdeb27f8c007a2b19adfe23c48e072d90f157cd033932dbd773cb47c55dad/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f50454d535f4241592e706e67\" alt=\"图片2\" style=\"flex: 1; max-width: 300px; height: auto;\">\n</div>\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Speed/\n\n## Pedestrian Datasets\nThe pedestrian datasets are collected from open data website of Melbourne. The full datasets' timespan is over 10 years and the datasets are still being updated at a fixed frequency (i.e., 60 minutes). Due to the fact that some sites were not set up in the early days and some sites lacked data, we only choose about a year in temporal dimension and 55 stations in spatial dimension. There is also accessible information about sensors on the same website. In the dataset of sensor information, we obtain the name, the sensor's ID, the sensor's status(whether it is active or not), the latitude and longtitude of each sensor.\nFollowing shows the map-visualization of Pedestrian datasets in Melbourne.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Pedestrain_Melbourne.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Pedestrian\n\n## Taxi Datasets\nThe Taxi datasets are collected from the city of Chicago's open data portal and the city of New York's open data portal, where you are able to freely download Chicago city's and NYC's datasets for your own analysis. The datasets record taxi trips from these dimensions listed below: pickup and dropoff time, pickup and dropoff location, fee etc. In our dataset, we only consider the pickup info of each record. You can conduct more comprehensive analysis with the help of our datasets and the website.\n\nTaxi Chicago Dataset\nFacts in dataset description\n\nThere are two candidate spatial discretization information: census tract and community area.\nFor each record, it will aggregate census tract granularity into community area due to privacy preserve.\nWhich granularity to choose\n\nThus, we need to choose a proper granularity. According to the needs of downstream tasks (Spatio-temporal traffic prediction), we summarize two principles of spatial granularity selection:\n\nSpatial granularity as small as possible (especially in high-demand area).\nDemamd aggregated due to privacy as few as possible.\nOn one hand, time distribution of taxi demand in downtown is dense, and the probability of being aggregated is small. on the other hand, the time distribution of taxi demand in the suburbs is sparse, and the probability of being aggregated is high.\n\nFinal datasets we open\n\nWe finally choose to process two datasets: one is Taxi_Chicago, where only spatial granularity community area is used; another is Taxi_fine_grained_Chicago, where community area is used in suburbs while census tract is used in downtown.\n\nWe highly recommend that you conduct more analysis on Taxi_fine_grained_Chicago. By the way, we have adopted a special operation that taxi demand of specific census tract in 15-minute time window equal or less than 2 will be set 2. This operation won't affect much because all of aggregation situation is ultimately caused by insufficient demand.\n\nFollowing shows the map-visualization of Taxi_Chicago datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Chicago_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nFollowing shows the map-visualization of Taxi_fine_grained_Chicago datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Chicago_fine_grained_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nTaxi NYC Datasets\nWe collect Taxi NYC dataset from these two websites: https://opendata.cityofnewyork.us/ and https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page. We also obtain information of taxi zones in New York from this website. As a result of size of dataset, we put it on the link with extraction code gw6p.\n\nFollowing shows the map-visualization of Taxi_NYC datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Taxi\n\n## Metro Datasets\nThe metro datasets are collected from DATA.NY.GOV: MTA Subway Hourly Ridership. The Metro_NYC dataset is provided by the Metropolitan Transportation Authority and is available for public download. It offers estimates of subway ridership on an hourly basis by subway station complex. Data collection started from February 2022 and has been regularly updated. The Metro_NYC dataset includes data up to December 21, 2023. The latest version can be accessed on the website mentioned above.\n\nFollowing shows the map-visualization of station complex in NYC.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Metro.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Metro\n\n## Flow Speed Datasets\nThe traffic flow datasets are collected from UTD19 - Research Collection. UTD19 is a large-scale traffic data set from over 20000 stationary detectors on urban roads in 40 cities worldwide making it the largest multi-city traffic data set publically available. In our dataset, we only consider the data for the city of Luzern. The dataset enriched location information of sensors with further attributes describing the location of the sensor with respect to the road network.\nFollowing shows the map-visualization of station complex in Luzern.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Luzern_Flow.png\" alt=\"Image\" style=\"max-width: 400px; height: auto;\">\n\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Flow\n\n## Load UCTB Dataset\n\n<!-- TODO: 介绍pickle -->\nThe `pickle` module is an external library that comes built-in with Python and provides functionality for converting Python objects into a byte stream (serialization) and restoring them back to their original state (deserialization). We use it to help data format instances to transform between memory and disk.\n\n### Dataset format\n\nWe've collected some public datasets and processing them into UCTB dataset format. UCTB dataset is a python build-in dictionary object that could be loaded by pickle package. Here is the example of UCTB dataset. \n\n```python\n# Let's say ``my_dataset`` is your dataset.\nmy_dataset = {\n    \"TimeRange\": ['YYYY-MM-DD', 'YYYY-MM-DD'],\n    \"TimeFitness\": 60, # Minutes\n    \n    \"Node\": {\n        \"TrafficNode\": np.array, # With shape [time, num-of-node]\n        \"TrafficMonthlyInteraction\": np.array, # With shape [month, num-of-node. num-of-node]\n        \"StationInfo\": list # elements in it should be [id, build-time, lat, lng, name]\n        \"POI\": []\n    },\n\n    \"Grid\": {\n        \"TrafficGrid\": [],\n        \"GridLatLng\": [],\n        \"POI\": []\n    },\n\n    \"ExternalFeature\": {\n         \"Weather\": [time, weather-feature-dim]\n    }\n}\n```\n\n### Use datasets from Urban Datasets\n\nIn this section, we will introduce how to get the dataset from Urban_Dataset and read the dataset using python.\n\nYou are proposed to download the zip file from the [link](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip) and unzip the file. Let's say the following scripts are placed at the same directory with the dataset.\n\n```python\nimport pickle as pkl\nimport numpy as np\ndata_path = 'Pedestrian_Melbourne.pkl'\nwith open(data_path,'rb') as fp:\n    data = pkl.load(fp)\n```\n\nTake a look at the necessary information about the dataset:\n\n```python\n# Traffic data \nprint('Data time range', data['TimeRange'])\nprint('Traffic data shape:', np.shape(data['Node']['TrafficNode']))\n# The first dimension of data['Node']['TrafficNode'] is the length of time-sequence.\n# The second dimension is the number of stations.\nprint('Time fitness:', data['TimeFitness'], 'minutes')\nprint('Time sequence length:', data['Node']['TrafficNode'].shape[0])\nprint('Number of stations:', data['Node']['TrafficNode'].shape[1])\n```\n\n    Data time range ['2021-01-01', '2022-11-01']\n    Traffic data shape: (16056, 55)\n    Time fitness: 60 minutes\n    Time sequence length: 16056\n    Number of stations: 55\n\nVisualize the distribution of the traffic data:\n\n```python\nimport matplotlib.pyplot as plt\nplt.plot(data['Node']['TrafficNode'][:, 0])\nplt.show()\n```\n\n![png](src/image/toturial_p1_dataplot.png)\n\n## How to get the datasets at other granularities?\nWe could merge the fine-grained data to obtain the datasets at other granularities (e.g., by summing the 12 flows from the 5-minutes datasets to obtain 60-minutes datasets). UCTB provides the API to merge data. You could specify MergeIndex and MergeWay in the NodeTrafficLoader and GridTrafficLoader. Here is an example:\n```python\nfrom UCTB.dataset import NodeTrafficLoader\n\n# loading 5-minutes datasets\n\ndata_loader = NodeTrafficLoader(dataset=\"Bike\", city=\"NYC\") \nprint(data_loader.dataset.node_traffic.shape) # with shape (446976, 820)\n\ndata_loader = NodeTrafficLoader(dataset=\"Bike\", city=\"NYC\", MergeIndex=12, MergeWay=\"sum\")\nprint(data_loader.dataset.node_traffic.shape) # with shape (37248, 820)\n```\n## Build your own datasets\n\nIf you want to apply uctb dataloaders to your dataset, make your dataset compatible with the template as section 3.2.1 shown. And then save it with package ``pickle`` to a local path ``pkl_file_name``.\n\n```python\nimport pickle\npkl_file_name = './my_dataset.pkl'  \nwith open(pkl_file_name, 'wb') as handle:\n    pickle.dump(my_dataset, handle, protocol=pickle.HIGHEST_PROTOCOL)\n```\n\nFinally, you can make uses of your dataset by UCTB's loader APIs:\n\n```python\ndata_loader = NodeTrafficLoader(dataset=pkl_file_name)\n```\n\nAlso, we provide interface to help build your own dataset, through which we clarify whether a field is necessary or optional when building a UCTB dataset.\n\nTo build a UCTB dataset, it is necessary to provide variables listed as below.\n\n|Variable_name|Description|\n|:--|:--|\n|time_fitness|The length of the interval between adjacent slots|\n|time_range| The time interval at the beginning and end of the data |\n|traffic_node| The spatio-temporal information |\n|node_satation_info| The basic information of each data collecting node |\n|dataset_name| Name of the dataset |\n|city| A variable used to integrate holiday and weather information to traffic data|\n\nThen, use the specified path to save the dataset, otherwise it will be saved in the current run-time path.\n\nAlthough it's diffcult to form an integrated function to include all situation you may meet during the transforming process, there are some procedures you might obey to simplify the data preprocessing.\n\n- Data preprocessing\n    1. Zero values\n    2. Missing values(NA)\n    3. Unknown values\n    4. Abnormal values\n    5. duplicates\n    6. Statistics(station number and time slots)\n- Dictionary building\n    - Basic information(time range and time fitness)\n    - Traffic node building\n        - Spatio-temporal raster data building\n            1. Initialization\n            2. iterate raw data table and fill the matrix\n        - Station information\n    - Traffic grid building\n    - External feature\n\nNow, we assume that you have already finished variable preparation. UCTB provide API to assist you with dataset building.\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago')\n```\n\nAlso, if you want to check what fields are in your datasets, set the argument ``print_dataset`` to ``True``.\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago', print_dataset=True)\n```\n\nOutput:\n\n    dataset[TimeRange]:<class 'list'>  (len=2)\n    dataset[TimeFitness]:<class 'int'>\n    dataset[Node]:<class 'dict'>{\n        dataset[Node][TrafficNode]:<class 'numpy.ndarray'>  (shape=(37248, 532))\n        dataset[Node][StationInfo]:<class 'list'>  (len=(532, 5))\n        dataset[Node][TrafficMonthlyInteraction]:<class 'NoneType'>\n    }\n    dataset[Grid]:<class 'dict'>{\n        dataset[Grid][TrafficGrid]:<class 'NoneType'>\n        dataset[Grid][GridLatLng]:<class 'NoneType'>\n    }\n    dataset[ExternalFeature]:<class 'dict'>{\n        dataset[ExternalFeature][Weather]:<class 'list'>  (len=0)\n    }\n    dataset[LenTimeSlots]:<class 'int'>\n\nWhat's more, if you want to integrate additional information of the dataset, just specify the optional argument as bellow.\n\n|Variable_name|Description|\n|:--|:--|\n|traffic_monthly_interaction| The interactive information among data collecting nodes. |\n|node_poi| Point of interests conformed with node format|\n|grid_poi| Point of interests conformed with grid format|\n|traffic_grid| The spatio-temporal information in grid format. |\n|gird_lat_lng| The basic information of each data collecting grid.|\n|external_feature_weather| The weather information of each day. |\n\nfor example, specify the argument ``external_feature_weather`` with numpy.array object.\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago', \n                print_dataset=True, external_feature_weather=np.zeros([37248,26]))\n```\n\nThe code above use zero matrix to specify the argument ``external_feature_weather``. While in practical application scenario, you should substitute it with real feather matrix. The first dimension of the matrx is the number of time slots, and the second dimension corresponds to the dimension of weather features."
  },
  {
    "path": "docs/_sources/md_file/visualization_tool.md.txt",
    "content": "# Visualization-tool\n\nWe have developed a tool that integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis. Welcome to visit the [website](http://39.107.116.221/) for a trial.\n\n## Quick Start\n\n### Start with predefined dataset\n\nYou can click on the dropdown menu in the `predefined` module of the `Data Loader`, select the dataset you need, and click `confirm` to obtain the required diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_1.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n### Start with prediction and ground truth\n\nYou can upload specifically formatted TSV files for prediction and ground truth in the `upload` module of the Data Loader. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_2.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n### Start with prediction, ground truth and spatial information\n\nYou can upload specifically formatted TSV files for prediction, ground truth, and spatial information in the `upload` module of the `Data Loader`. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_3.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n###  Start with prediction, ground truth and temporal information\n\nYou can upload specifically formatted TSV files for prediction, and ground truth in the `upload` module of the 'Data Loader', along with the corresponding temporal information. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_4.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n### Start with prediction, ground truth as well as spatial and temporal information\n\nYou can upload specifically formatted TSV files for prediction, ground truth, and spatial information in the `upload` module of the `Data Loader`, along with the corresponding temporal information. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_5.png\" alt=\".img\" style=\"zoom: 33%;\" />\n\n## Contribute to our project.\n\nThe visualization-tool offers two usage options, which are accessing through the [website](http://39.107.116.221/), or using the source code(for contribution).\n\n**Step 1: Requirements**\n\n```vue\nnode == 16.14.0\nnpm == 8.3.1\n```\n\n**Step 2: Clone repository and install dependencies**\n\n```Vue\ngit clone https://github.com/uctb/visualization-tool-UCTB.git \ncd visualization-tool-UCTB \nnpm install\n```\n\n**Step 3: Start**\n\n```Vue\nnpm run serve\n```\n\nThen you will see the following prompt on the screen:\n\n```vue\n App running at:\n  - Local:   http://localhost:xxxx/ \n  - Network: http://ip:xxxx/\n```\n\nYou can customize the visualization tool in the source code to achieve visual effects that better fit the objectives. To better assist you in achieving personalization of the visualization tool, we recommend following these steps to implement it.\n\n**Step 1: Create your own component**\n\n```vue\n<template>\n<div>Your own HTML</div>\n</template>\n\n<script>\nexport default {\n\tname: 'your own component name',\n    data(){}\n}\n</script>\n\n<style scoped>\n /*Your own CSS*/\n</style>\n```\n\n**Step 2: Importing component in App.vue**\n\n```vue\n<script>\nimport YourOwnComponent from \"./components/YourOwnComponent.vue\"\nexport default {\n\tname: 'App',\n    components: {\n     YourOwnComponent\n    }\n}\n</script>\n```\n\nMore instructions on the usage of Vue can be referred to on the [website](https://v2.vuejs.org/). **If you have any interesting or novel ideas, we highly welcome your pull request:)**"
  },
  {
    "path": "docs/_sources/modules.rst.txt",
    "content": "UCTB\n====\n\n.. toctree::\n   :maxdepth: 4\n\n   UCTB\n"
  },
  {
    "path": "docs/_sources/update_guide.txt",
    "content": "The first thing is to install the UCTB library, in fact, if you want to update successfully, you must first install the UCTB library successfully。\n\nThe second thing to do is to install the Sphinx-related library functions locally. Here are some of the related versions。\npip install Sphinx==5.1.1\npip install sphinx-markdown-tables==0.0.17\npip install sphinx-rtd-theme==1.2.1\npip install sphinxcontrib-applehelp==1.0.2\npip install sphinxcontrib-devhelp==1.0.2\npip install sphinxcontrib-htmlhelp==2.0.0\npip install sphinxcontrib-jsmath==1.0.1\npip install sphinxcontrib-qthelp==1.0.3\npip install sphinxcontrib-serializinghtml==1.1.5\npip install rtcat-sphinx-theme==0.1.1\npip install recommonmark==0.7.1\npip install commonmark==0.9.1\npip install sphinx-markdown-tables==0.0.17\n\nNext, locate the.md file that corresponds to the section you want to update,\nIf you want to add text, just copy and paste it, if you want to add a big title, you can use the form of a # title, if you want to add a secondary title, you can use the form of a ## title, and so on.\n\nWhen update docstrings, run this code in cmd:\nsphinx-apidoc -o . ../../UCTB\nsphinx-build -b html . ..\nsphinx-build -b html . _build\nThen you can get the html file generated after the update.\n"
  },
  {
    "path": "docs/_static/_sphinx_javascript_frameworks_compat.js",
    "content": "/*\n * _sphinx_javascript_frameworks_compat.js\n * ~~~~~~~~~~\n *\n * Compatability shim for jQuery and underscores.js.\n *\n * WILL BE REMOVED IN Sphinx 6.0\n * xref RemovedInSphinx60Warning\n *\n */\n\n/**\n * select a different prefix for underscore\n */\n$u = _.noConflict();\n\n\n/**\n * small helper function to urldecode strings\n *\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL\n */\njQuery.urldecode = function(x) {\n    if (!x) {\n        return x\n    }\n    return decodeURIComponent(x.replace(/\\+/g, ' '));\n};\n\n/**\n * small helper function to urlencode strings\n */\njQuery.urlencode = encodeURIComponent;\n\n/**\n * This function returns the parsed url parameters of the\n * current request. Multiple values per key are supported,\n * it will always return arrays of strings for the value parts.\n */\njQuery.getQueryParameters = function(s) {\n    if (typeof s === 'undefined')\n        s = document.location.search;\n    var parts = s.substr(s.indexOf('?') + 1).split('&');\n    var result = {};\n    for (var i = 0; i < parts.length; i++) {\n        var tmp = parts[i].split('=', 2);\n        var key = jQuery.urldecode(tmp[0]);\n        var value = jQuery.urldecode(tmp[1]);\n        if (key in result)\n            result[key].push(value);\n        else\n            result[key] = [value];\n    }\n    return result;\n};\n\n/**\n * highlight a given string on a jquery object by wrapping it in\n * span elements with the given class name.\n */\njQuery.fn.highlightText = function(text, className) {\n    function highlight(node, addItems) {\n        if (node.nodeType === 3) {\n            var val = node.nodeValue;\n            var pos = val.toLowerCase().indexOf(text);\n            if (pos >= 0 &&\n                !jQuery(node.parentNode).hasClass(className) &&\n                !jQuery(node.parentNode).hasClass(\"nohighlight\")) {\n                var span;\n                var isInSVG = jQuery(node).closest(\"body, svg, foreignObject\").is(\"svg\");\n                if (isInSVG) {\n                    span = document.createElementNS(\"http://www.w3.org/2000/svg\", \"tspan\");\n                } else {\n                    span = document.createElement(\"span\");\n                    span.className = className;\n                }\n                span.appendChild(document.createTextNode(val.substr(pos, text.length)));\n                node.parentNode.insertBefore(span, node.parentNode.insertBefore(\n                    document.createTextNode(val.substr(pos + text.length)),\n                    node.nextSibling));\n                node.nodeValue = val.substr(0, pos);\n                if (isInSVG) {\n                    var rect = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n                    var bbox = node.parentElement.getBBox();\n                    rect.x.baseVal.value = bbox.x;\n                    rect.y.baseVal.value = bbox.y;\n                    rect.width.baseVal.value = bbox.width;\n                    rect.height.baseVal.value = bbox.height;\n                    rect.setAttribute('class', className);\n                    addItems.push({\n                        \"parent\": node.parentNode,\n                        \"target\": rect});\n                }\n            }\n        }\n        else if (!jQuery(node).is(\"button, select, textarea\")) {\n            jQuery.each(node.childNodes, function() {\n                highlight(this, addItems);\n            });\n        }\n    }\n    var addItems = [];\n    var result = this.each(function() {\n        highlight(this, addItems);\n    });\n    for (var i = 0; i < addItems.length; ++i) {\n        jQuery(addItems[i].parent).before(addItems[i].target);\n    }\n    return result;\n};\n\n/*\n * backward compatibility for jQuery.browser\n * This will be supported until firefox bug is fixed.\n */\nif (!jQuery.browser) {\n    jQuery.uaMatch = function(ua) {\n        ua = ua.toLowerCase();\n\n        var match = /(chrome)[ \\/]([\\w.]+)/.exec(ua) ||\n            /(webkit)[ \\/]([\\w.]+)/.exec(ua) ||\n            /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec(ua) ||\n            /(msie) ([\\w.]+)/.exec(ua) ||\n            ua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec(ua) ||\n            [];\n\n        return {\n            browser: match[ 1 ] || \"\",\n            version: match[ 2 ] || \"0\"\n        };\n    };\n    jQuery.browser = {};\n    jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;\n}\n"
  },
  {
    "path": "docs/_static/alabaster.css",
    "content": "@import url(\"basic.css\");\n\n/* -- page layout ----------------------------------------------------------- */\n\nbody {\n    font-family: Georgia, serif;\n    font-size: 17px;\n    background-color: #fff;\n    color: #000;\n    margin: 0;\n    padding: 0;\n}\n\n\ndiv.document {\n    width: 940px;\n    margin: 30px auto 0 auto;\n}\n\ndiv.documentwrapper {\n    float: left;\n    width: 100%;\n}\n\ndiv.bodywrapper {\n    margin: 0 0 0 220px;\n}\n\ndiv.sphinxsidebar {\n    width: 220px;\n    font-size: 14px;\n    line-height: 1.5;\n}\n\nhr {\n    border: 1px solid #B1B4B6;\n}\n\ndiv.body {\n    background-color: #fff;\n    color: #3E4349;\n    padding: 0 30px 0 30px;\n}\n\ndiv.body > .section {\n    text-align: left;\n}\n\ndiv.footer {\n    width: 940px;\n    margin: 20px auto 30px auto;\n    font-size: 14px;\n    color: #888;\n    text-align: right;\n}\n\ndiv.footer a {\n    color: #888;\n}\n\np.caption {\n    font-family: inherit;\n    font-size: inherit;\n}\n\n\ndiv.relations {\n    display: none;\n}\n\n\ndiv.sphinxsidebar a {\n    color: #444;\n    text-decoration: none;\n    border-bottom: 1px dotted #999;\n}\n\ndiv.sphinxsidebar a:hover {\n    border-bottom: 1px solid #999;\n}\n\ndiv.sphinxsidebarwrapper {\n    padding: 18px 10px;\n}\n\ndiv.sphinxsidebarwrapper p.logo {\n    padding: 0;\n    margin: -10px 0 0 0px;\n    text-align: center;\n}\n\ndiv.sphinxsidebarwrapper h1.logo {\n    margin-top: -10px;\n    text-align: center;\n    margin-bottom: 5px;\n    text-align: left;\n}\n\ndiv.sphinxsidebarwrapper h1.logo-name {\n    margin-top: 0px;\n}\n\ndiv.sphinxsidebarwrapper p.blurb {\n    margin-top: 0;\n    font-style: normal;\n}\n\ndiv.sphinxsidebar h3,\ndiv.sphinxsidebar h4 {\n    font-family: Georgia, serif;\n    color: #444;\n    font-size: 24px;\n    font-weight: normal;\n    margin: 0 0 5px 0;\n    padding: 0;\n}\n\ndiv.sphinxsidebar h4 {\n    font-size: 20px;\n}\n\ndiv.sphinxsidebar h3 a {\n    color: #444;\n}\n\ndiv.sphinxsidebar p.logo a,\ndiv.sphinxsidebar h3 a,\ndiv.sphinxsidebar p.logo a:hover,\ndiv.sphinxsidebar h3 a:hover {\n    border: none;\n}\n\ndiv.sphinxsidebar p {\n    color: #555;\n    margin: 10px 0;\n}\n\ndiv.sphinxsidebar ul {\n    margin: 10px 0;\n    padding: 0;\n    color: #000;\n}\n\ndiv.sphinxsidebar ul li.toctree-l1 > a {\n    font-size: 120%;\n}\n\ndiv.sphinxsidebar ul li.toctree-l2 > a {\n    font-size: 110%;\n}\n\ndiv.sphinxsidebar input {\n    border: 1px solid #CCC;\n    font-family: Georgia, serif;\n    font-size: 1em;\n}\n\ndiv.sphinxsidebar hr {\n    border: none;\n    height: 1px;\n    color: #AAA;\n    background: #AAA;\n\n    text-align: left;\n    margin-left: 0;\n    width: 50%;\n}\n\ndiv.sphinxsidebar .badge {\n    border-bottom: none;\n}\n\ndiv.sphinxsidebar .badge:hover {\n    border-bottom: none;\n}\n\n/* To address an issue with donation coming after search */\ndiv.sphinxsidebar h3.donation {\n    margin-top: 10px;\n}\n\n/* -- body styles ----------------------------------------------------------- */\n\na {\n    color: #004B6B;\n    text-decoration: underline;\n}\n\na:hover {\n    color: #6D4100;\n    text-decoration: underline;\n}\n\ndiv.body h1,\ndiv.body h2,\ndiv.body h3,\ndiv.body h4,\ndiv.body h5,\ndiv.body h6 {\n    font-family: Georgia, serif;\n    font-weight: normal;\n    margin: 30px 0px 10px 0px;\n    padding: 0;\n}\n\ndiv.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }\ndiv.body h2 { font-size: 180%; }\ndiv.body h3 { font-size: 150%; }\ndiv.body h4 { font-size: 130%; }\ndiv.body h5 { font-size: 100%; }\ndiv.body h6 { font-size: 100%; }\n\na.headerlink {\n    color: #DDD;\n    padding: 0 4px;\n    text-decoration: none;\n}\n\na.headerlink:hover {\n    color: #444;\n    background: #EAEAEA;\n}\n\ndiv.body p, div.body dd, div.body li {\n    line-height: 1.4em;\n}\n\ndiv.admonition {\n    margin: 20px 0px;\n    padding: 10px 30px;\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.admonition tt.xref, div.admonition code.xref, div.admonition a tt {\n    background-color: #FBFBFB;\n    border-bottom: 1px solid #fafafa;\n}\n\ndiv.admonition p.admonition-title {\n    font-family: Georgia, serif;\n    font-weight: normal;\n    font-size: 24px;\n    margin: 0 0 10px 0;\n    padding: 0;\n    line-height: 1;\n}\n\ndiv.admonition p.last {\n    margin-bottom: 0;\n}\n\ndiv.highlight {\n    background-color: #fff;\n}\n\ndt:target, .highlight {\n    background: #FAF3E8;\n}\n\ndiv.warning {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n}\n\ndiv.danger {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n    -moz-box-shadow: 2px 2px 4px #D52C2C;\n    -webkit-box-shadow: 2px 2px 4px #D52C2C;\n    box-shadow: 2px 2px 4px #D52C2C;\n}\n\ndiv.error {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n    -moz-box-shadow: 2px 2px 4px #D52C2C;\n    -webkit-box-shadow: 2px 2px 4px #D52C2C;\n    box-shadow: 2px 2px 4px #D52C2C;\n}\n\ndiv.caution {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n}\n\ndiv.attention {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n}\n\ndiv.important {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.note {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.tip {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.hint {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.seealso {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.topic {\n    background-color: #EEE;\n}\n\np.admonition-title {\n    display: inline;\n}\n\np.admonition-title:after {\n    content: \":\";\n}\n\npre, tt, code {\n    font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;\n    font-size: 0.9em;\n}\n\n.hll {\n    background-color: #FFC;\n    margin: 0 -12px;\n    padding: 0 12px;\n    display: block;\n}\n\nimg.screenshot {\n}\n\ntt.descname, tt.descclassname, code.descname, code.descclassname {\n    font-size: 0.95em;\n}\n\ntt.descname, code.descname {\n    padding-right: 0.08em;\n}\n\nimg.screenshot {\n    -moz-box-shadow: 2px 2px 4px #EEE;\n    -webkit-box-shadow: 2px 2px 4px #EEE;\n    box-shadow: 2px 2px 4px #EEE;\n}\n\ntable.docutils {\n    border: 1px solid #888;\n    -moz-box-shadow: 2px 2px 4px #EEE;\n    -webkit-box-shadow: 2px 2px 4px #EEE;\n    box-shadow: 2px 2px 4px #EEE;\n}\n\ntable.docutils td, table.docutils th {\n    border: 1px solid #888;\n    padding: 0.25em 0.7em;\n}\n\ntable.field-list, table.footnote {\n    border: none;\n    -moz-box-shadow: none;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n}\n\ntable.footnote {\n    margin: 15px 0;\n    width: 100%;\n    border: 1px solid #EEE;\n    background: #FDFDFD;\n    font-size: 0.9em;\n}\n\ntable.footnote + table.footnote {\n    margin-top: -15px;\n    border-top: none;\n}\n\ntable.field-list th {\n    padding: 0 0.8em 0 0;\n}\n\ntable.field-list td {\n    padding: 0;\n}\n\ntable.field-list p {\n    margin-bottom: 0.8em;\n}\n\n/* Cloned from\n * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68\n */\n.field-name {\n    -moz-hyphens: manual;\n    -ms-hyphens: manual;\n    -webkit-hyphens: manual;\n    hyphens: manual;\n}\n\ntable.footnote td.label {\n    width: .1px;\n    padding: 0.3em 0 0.3em 0.5em;\n}\n\ntable.footnote td {\n    padding: 0.3em 0.5em;\n}\n\ndl {\n    margin: 0;\n    padding: 0;\n}\n\ndl dd {\n    margin-left: 30px;\n}\n\nblockquote {\n    margin: 0 0 0 30px;\n    padding: 0;\n}\n\nul, ol {\n    /* Matches the 30px from the narrow-screen \"li > ul\" selector below */\n    margin: 10px 0 10px 30px;\n    padding: 0;\n}\n\npre {\n    background: #EEE;\n    padding: 7px 30px;\n    margin: 15px 0px;\n    line-height: 1.3em;\n}\n\ndiv.viewcode-block:target {\n    background: #ffd;\n}\n\ndl pre, blockquote pre, li pre {\n    margin-left: 0;\n    padding-left: 30px;\n}\n\ntt, code {\n    background-color: #ecf0f3;\n    color: #222;\n    /* padding: 1px 2px; */\n}\n\ntt.xref, code.xref, a tt {\n    background-color: #FBFBFB;\n    border-bottom: 1px solid #fff;\n}\n\na.reference {\n    text-decoration: none;\n    border-bottom: 1px dotted #004B6B;\n}\n\n/* Don't put an underline on images */\na.image-reference, a.image-reference:hover {\n    border-bottom: none;\n}\n\na.reference:hover {\n    border-bottom: 1px solid #6D4100;\n}\n\na.footnote-reference {\n    text-decoration: none;\n    font-size: 0.7em;\n    vertical-align: top;\n    border-bottom: 1px dotted #004B6B;\n}\n\na.footnote-reference:hover {\n    border-bottom: 1px solid #6D4100;\n}\n\na:hover tt, a:hover code {\n    background: #EEE;\n}\n\n\n@media screen and (max-width: 870px) {\n\n    div.sphinxsidebar {\n    \tdisplay: none;\n    }\n\n    div.document {\n       width: 100%;\n\n    }\n\n    div.documentwrapper {\n    \tmargin-left: 0;\n    \tmargin-top: 0;\n    \tmargin-right: 0;\n    \tmargin-bottom: 0;\n    }\n\n    div.bodywrapper {\n    \tmargin-top: 0;\n    \tmargin-right: 0;\n    \tmargin-bottom: 0;\n    \tmargin-left: 0;\n    }\n\n    ul {\n    \tmargin-left: 0;\n    }\n\n\tli > ul {\n        /* Matches the 30px from the \"ul, ol\" selector above */\n\t\tmargin-left: 30px;\n\t}\n\n    .document {\n    \twidth: auto;\n    }\n\n    .footer {\n    \twidth: auto;\n    }\n\n    .bodywrapper {\n    \tmargin: 0;\n    }\n\n    .footer {\n    \twidth: auto;\n    }\n\n    .github {\n        display: none;\n    }\n\n\n\n}\n\n\n\n@media screen and (max-width: 875px) {\n\n    body {\n        margin: 0;\n        padding: 20px 30px;\n    }\n\n    div.documentwrapper {\n        float: none;\n        background: #fff;\n    }\n\n    div.sphinxsidebar {\n        display: block;\n        float: none;\n        width: 102.5%;\n        margin: 50px -30px -20px -30px;\n        padding: 10px 20px;\n        background: #333;\n        color: #FFF;\n    }\n\n    div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,\n    div.sphinxsidebar h3 a {\n        color: #fff;\n    }\n\n    div.sphinxsidebar a {\n        color: #AAA;\n    }\n\n    div.sphinxsidebar p.logo {\n        display: none;\n    }\n\n    div.document {\n        width: 100%;\n        margin: 0;\n    }\n\n    div.footer {\n        display: none;\n    }\n\n    div.bodywrapper {\n        margin: 0;\n    }\n\n    div.body {\n        min-height: 0;\n        padding: 0;\n    }\n\n    .rtd_doc_footer {\n        display: none;\n    }\n\n    .document {\n        width: auto;\n    }\n\n    .footer {\n        width: auto;\n    }\n\n    .footer {\n        width: auto;\n    }\n\n    .github {\n        display: none;\n    }\n}\n\n\n/* misc. */\n\n.revsys-inline {\n    display: none!important;\n}\n\n/* Make nested-list/multi-paragraph items look better in Releases changelog\n * pages. Without this, docutils' magical list fuckery causes inconsistent\n * formatting between different release sub-lists.\n */\ndiv#changelog > div.section > ul > li > p:only-child {\n    margin-bottom: 0;\n}\n\n/* Hide fugly table cell borders in ..bibliography:: directive output */\ntable.docutils.citation, table.docutils.citation td, table.docutils.citation th {\n  border: none;\n  /* Below needed in some edge cases; if not applied, bottom shadows appear */\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n\n\n/* relbar */\n\n.related {\n    line-height: 30px;\n    width: 100%;\n    font-size: 0.9rem;\n}\n\n.related.top {\n    border-bottom: 1px solid #EEE;\n    margin-bottom: 20px;\n}\n\n.related.bottom {\n    border-top: 1px solid #EEE;\n}\n\n.related ul {\n    padding: 0;\n    margin: 0;\n    list-style: none;\n}\n\n.related li {\n    display: inline;\n}\n\nnav#rellinks {\n    float: right;\n}\n\nnav#rellinks li+li:before {\n    content: \"|\";\n}\n\nnav#breadcrumbs li+li:before {\n    content: \"\\00BB\";\n}\n\n/* Hide certain items when printing */\n@media print {\n    div.related {\n        display: none;\n    }\n}"
  },
  {
    "path": "docs/_static/basic.css",
    "content": "/*\n * basic.css\n * ~~~~~~~~~\n *\n * Sphinx stylesheet -- basic theme.\n *\n * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n/* -- main layout ----------------------------------------------------------- */\n\ndiv.clearer {\n    clear: both;\n}\n\n/* -- relbar ---------------------------------------------------------------- */\n\ndiv.related {\n    width: 100%;\n    font-size: 90%;\n}\n\ndiv.related h3 {\n    display: none;\n}\n\ndiv.related ul {\n    margin: 0;\n    padding: 0 0 0 10px;\n    list-style: none;\n}\n\ndiv.related li {\n    display: inline;\n}\n\ndiv.related li.right {\n    float: right;\n    margin-right: 5px;\n}\n\n/* -- sidebar --------------------------------------------------------------- */\n\ndiv.sphinxsidebarwrapper {\n    padding: 10px 5px 0 10px;\n}\n\ndiv.sphinxsidebar {\n    float: left;\n    width: 230px;\n    margin-left: -100%;\n    font-size: 90%;\n    word-wrap: break-word;\n    overflow-wrap : break-word;\n}\n\ndiv.sphinxsidebar ul {\n    list-style: none;\n}\n\ndiv.sphinxsidebar ul ul,\ndiv.sphinxsidebar ul.want-points {\n    margin-left: 20px;\n    list-style: square;\n}\n\ndiv.sphinxsidebar ul ul {\n    margin-top: 0;\n    margin-bottom: 0;\n}\n\ndiv.sphinxsidebar form {\n    margin-top: 10px;\n}\n\ndiv.sphinxsidebar input {\n    border: 1px solid #98dbcc;\n    font-family: sans-serif;\n    font-size: 1em;\n}\n\ndiv.sphinxsidebar #searchbox input[type=\"text\"] {\n    width: 170px;\n}\n\nimg {\n    border: 0;\n    max-width: 100%;\n}\n\n/* -- search page ----------------------------------------------------------- */\n\nul.search {\n    margin: 10px 0 0 20px;\n    padding: 0;\n}\n\nul.search li {\n    padding: 5px 0 5px 20px;\n    background-image: url(file.png);\n    background-repeat: no-repeat;\n    background-position: 0 7px;\n}\n\nul.search li a {\n    font-weight: bold;\n}\n\nul.search li div.context {\n    color: #888;\n    margin: 2px 0 0 30px;\n    text-align: left;\n}\n\nul.keywordmatches li.goodmatch a {\n    font-weight: bold;\n}\n\n/* -- index page ------------------------------------------------------------ */\n\ntable.contentstable {\n    width: 90%;\n    margin-left: auto;\n    margin-right: auto;\n}\n\ntable.contentstable p.biglink {\n    line-height: 150%;\n}\n\na.biglink {\n    font-size: 1.3em;\n}\n\nspan.linkdescr {\n    font-style: italic;\n    padding-top: 5px;\n    font-size: 90%;\n}\n\n/* -- general index --------------------------------------------------------- */\n\ntable.indextable {\n    width: 100%;\n}\n\ntable.indextable td {\n    text-align: left;\n    vertical-align: top;\n}\n\ntable.indextable ul {\n    margin-top: 0;\n    margin-bottom: 0;\n    list-style-type: none;\n}\n\ntable.indextable > tbody > tr > td > ul {\n    padding-left: 0em;\n}\n\ntable.indextable tr.pcap {\n    height: 10px;\n}\n\ntable.indextable tr.cap {\n    margin-top: 10px;\n    background-color: #f2f2f2;\n}\n\nimg.toggler {\n    margin-right: 3px;\n    margin-top: 3px;\n    cursor: pointer;\n}\n\ndiv.modindex-jumpbox {\n    border-top: 1px solid #ddd;\n    border-bottom: 1px solid #ddd;\n    margin: 1em 0 1em 0;\n    padding: 0.4em;\n}\n\ndiv.genindex-jumpbox {\n    border-top: 1px solid #ddd;\n    border-bottom: 1px solid #ddd;\n    margin: 1em 0 1em 0;\n    padding: 0.4em;\n}\n\n/* -- domain module index --------------------------------------------------- */\n\ntable.modindextable td {\n    padding: 2px;\n    border-collapse: collapse;\n}\n\n/* -- general body styles --------------------------------------------------- */\n\ndiv.body p, div.body dd, div.body li, div.body blockquote {\n    -moz-hyphens: auto;\n    -ms-hyphens: auto;\n    -webkit-hyphens: auto;\n    hyphens: auto;\n}\n\na.headerlink {\n    visibility: hidden;\n}\n\nh1:hover > a.headerlink,\nh2:hover > a.headerlink,\nh3:hover > a.headerlink,\nh4:hover > a.headerlink,\nh5:hover > a.headerlink,\nh6:hover > a.headerlink,\ndt:hover > a.headerlink,\ncaption:hover > a.headerlink,\np.caption:hover > a.headerlink,\ndiv.code-block-caption:hover > a.headerlink {\n    visibility: visible;\n}\n\ndiv.body p.caption {\n    text-align: inherit;\n}\n\ndiv.body td {\n    text-align: left;\n}\n\n.first {\n    margin-top: 0 !important;\n}\n\np.rubric {\n    margin-top: 30px;\n    font-weight: bold;\n}\n\nimg.align-left, .figure.align-left, object.align-left {\n    clear: left;\n    float: left;\n    margin-right: 1em;\n}\n\nimg.align-right, .figure.align-right, object.align-right {\n    clear: right;\n    float: right;\n    margin-left: 1em;\n}\n\nimg.align-center, .figure.align-center, object.align-center {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n\n.align-left {\n    text-align: left;\n}\n\n.align-center {\n    text-align: center;\n}\n\n.align-right {\n    text-align: right;\n}\n\n/* -- sidebars -------------------------------------------------------------- */\n\ndiv.sidebar {\n    margin: 0 0 0.5em 1em;\n    border: 1px solid #ddb;\n    padding: 7px 7px 0 7px;\n    background-color: #ffe;\n    width: 40%;\n    float: right;\n}\n\np.sidebar-title {\n    font-weight: bold;\n}\n\n/* -- topics ---------------------------------------------------------------- */\n\ndiv.topic {\n    border: 1px solid #ccc;\n    padding: 7px 7px 0 7px;\n    margin: 10px 0 10px 0;\n}\n\np.topic-title {\n    font-size: 1.1em;\n    font-weight: bold;\n    margin-top: 10px;\n}\n\n/* -- admonitions ----------------------------------------------------------- */\n\ndiv.admonition {\n    margin-top: 10px;\n    margin-bottom: 10px;\n    padding: 7px;\n}\n\ndiv.admonition dt {\n    font-weight: bold;\n}\n\ndiv.admonition dl {\n    margin-bottom: 0;\n}\n\np.admonition-title {\n    margin: 0px 10px 5px 0px;\n    font-weight: bold;\n}\n\ndiv.body p.centered {\n    text-align: center;\n    margin-top: 25px;\n}\n\n/* -- tables ---------------------------------------------------------------- */\n\ntable.docutils {\n    border: 0;\n    border-collapse: collapse;\n}\n\ntable caption span.caption-number {\n    font-style: italic;\n}\n\ntable caption span.caption-text {\n}\n\ntable.docutils td, table.docutils th {\n    padding: 1px 8px 1px 5px;\n    border-top: 0;\n    border-left: 0;\n    border-right: 0;\n    border-bottom: 1px solid #aaa;\n}\n\ntable.footnote td, table.footnote th {\n    border: 0 !important;\n}\n\nth {\n    text-align: left;\n    padding-right: 5px;\n}\n\ntable.citation {\n    border-left: solid 1px gray;\n    margin-left: 1px;\n}\n\ntable.citation td {\n    border-bottom: none;\n}\n\n/* -- figures --------------------------------------------------------------- */\n\ndiv.figure {\n    margin: 0.5em;\n    padding: 0.5em;\n}\n\ndiv.figure p.caption {\n    padding: 0.3em;\n}\n\ndiv.figure p.caption span.caption-number {\n    font-style: italic;\n}\n\ndiv.figure p.caption span.caption-text {\n}\n\n/* -- field list styles ----------------------------------------------------- */\n\ntable.field-list td, table.field-list th {\n    border: 0 !important;\n}\n\n.field-list ul {\n    margin: 0;\n    padding-left: 1em;\n}\n\n.field-list p {\n    margin: 0;\n}\n\n.field-name {\n    -moz-hyphens: manual;\n    -ms-hyphens: manual;\n    -webkit-hyphens: manual;\n    hyphens: manual;\n}\n\n/* -- other body styles ----------------------------------------------------- */\n\nol.arabic {\n    list-style: decimal;\n}\n\nol.loweralpha {\n    list-style: lower-alpha;\n}\n\nol.upperalpha {\n    list-style: upper-alpha;\n}\n\nol.lowerroman {\n    list-style: lower-roman;\n}\n\nol.upperroman {\n    list-style: upper-roman;\n}\n\ndl {\n    margin-bottom: 15px;\n}\n\ndd p {\n    margin-top: 0px;\n}\n\ndd ul, dd table {\n    margin-bottom: 10px;\n}\n\ndd {\n    margin-top: 3px;\n    margin-bottom: 10px;\n    margin-left: 30px;\n}\n\ndt:target, .highlighted {\n    background-color: #fbe54e;\n}\n\ndl.glossary dt {\n    font-weight: bold;\n    font-size: 1.1em;\n}\n\n.optional {\n    font-size: 1.3em;\n}\n\n.sig-paren {\n    font-size: larger;\n}\n\n.versionmodified {\n    font-style: italic;\n}\n\n.system-message {\n    background-color: #fda;\n    padding: 5px;\n    border: 3px solid red;\n}\n\n.footnote:target  {\n    background-color: #ffa;\n}\n\n.line-block {\n    display: block;\n    margin-top: 1em;\n    margin-bottom: 1em;\n}\n\n.line-block .line-block {\n    margin-top: 0;\n    margin-bottom: 0;\n    margin-left: 1.5em;\n}\n\n.guilabel, .menuselection {\n    font-family: sans-serif;\n}\n\n.accelerator {\n    text-decoration: underline;\n}\n\n.classifier {\n    font-style: oblique;\n}\n\nabbr, acronym {\n    border-bottom: dotted 1px;\n    cursor: help;\n}\n\n/* -- code displays --------------------------------------------------------- */\n\npre {\n    overflow: auto;\n    overflow-y: hidden;  /* fixes display issues on Chrome browsers */\n}\n\nspan.pre {\n    -moz-hyphens: none;\n    -ms-hyphens: none;\n    -webkit-hyphens: none;\n    hyphens: none;\n}\n\ntd.linenos pre {\n    padding: 5px 0px;\n    border: 0;\n    background-color: transparent;\n    color: #aaa;\n}\n\ntable.highlighttable {\n    margin-left: 0.5em;\n}\n\ntable.highlighttable td {\n    padding: 0 0.5em 0 0.5em;\n}\n\ndiv.code-block-caption {\n    padding: 2px 5px;\n    font-size: small;\n}\n\ndiv.code-block-caption code {\n    background-color: transparent;\n}\n\ndiv.code-block-caption + div > div.highlight > pre {\n    margin-top: 0;\n}\n\ndiv.code-block-caption span.caption-number {\n    padding: 0.1em 0.3em;\n    font-style: italic;\n}\n\ndiv.code-block-caption span.caption-text {\n}\n\ndiv.literal-block-wrapper {\n    padding: 1em 1em 0;\n}\n\ndiv.literal-block-wrapper div.highlight {\n    margin: 0;\n}\n\ncode.descname {\n    background-color: transparent;\n    font-weight: bold;\n    font-size: 1.2em;\n}\n\ncode.descclassname {\n    background-color: transparent;\n}\n\ncode.xref, a code {\n    background-color: transparent;\n    font-weight: bold;\n}\n\nh1 code, h2 code, h3 code, h4 code, h5 code, h6 code {\n    background-color: transparent;\n}\n\n.viewcode-link {\n    float: right;\n}\n\n.viewcode-back {\n    float: right;\n    font-family: sans-serif;\n}\n\ndiv.viewcode-block:target {\n    margin: -1px -10px;\n    padding: 0 10px;\n}\n\n/* -- math display ---------------------------------------------------------- */\n\nimg.math {\n    vertical-align: middle;\n}\n\ndiv.body div.math p {\n    text-align: center;\n}\n\nspan.eqno {\n    float: right;\n}\n\nspan.eqno a.headerlink {\n    position: relative;\n    left: 0px;\n    z-index: 1;\n}\n\ndiv.math:hover a.headerlink {\n    visibility: visible;\n}\n\n/* -- printout stylesheet --------------------------------------------------- */\n\n@media print {\n    div.document,\n    div.documentwrapper,\n    div.bodywrapper {\n        margin: 0 !important;\n        width: 100%;\n    }\n\n    div.sphinxsidebar,\n    div.related,\n    div.footer,\n    #top-link {\n        display: none;\n    }\n}"
  },
  {
    "path": "docs/_static/css/badge_only.css",
    "content": "@charset \"UTF-8\";\n.fa:before {\n  -webkit-font-smoothing: antialiased;\n}\n\n.clearfix {\n  *zoom: 1;\n}\n.clearfix:before, .clearfix:after {\n  display: table;\n  content: \"\";\n}\n.clearfix:after {\n  clear: both;\n}\n\n@font-face {\n  font-family: FontAwesome;\n  font-weight: normal;\n  font-style: normal;\n  src: url(\"../font/fontawesome_webfont.eot\");\n  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\");\n}\n.fa:before {\n  display: inline-block;\n  font-family: FontAwesome;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  text-decoration: inherit;\n}\n\na .fa {\n  display: inline-block;\n  text-decoration: inherit;\n}\n\nli .fa {\n  display: inline-block;\n}\nli .fa-large:before,\nli .fa-large:before {\n  /* 1.5 increased font size for fa-large * 1.25 width */\n  width: 1.875em;\n}\n\nul.fas {\n  list-style-type: none;\n  margin-left: 2em;\n  text-indent: -0.8em;\n}\nul.fas li .fa {\n  width: 0.8em;\n}\nul.fas li .fa-large:before,\nul.fas li .fa-large:before {\n  /* 1.5 increased font size for fa-large * 1.25 width */\n  vertical-align: baseline;\n}\n\n.fa-book:before {\n  content: \"\";\n}\n\n.icon-book:before {\n  content: \"\";\n}\n\n.fa-caret-down:before {\n  content: \"\";\n}\n\n.icon-caret-down:before {\n  content: \"\";\n}\n\n.fa-caret-up:before {\n  content: \"\";\n}\n\n.icon-caret-up:before {\n  content: \"\";\n}\n\n.fa-caret-left:before {\n  content: \"\";\n}\n\n.icon-caret-left:before {\n  content: \"\";\n}\n\n.fa-caret-right:before {\n  content: \"\";\n}\n\n.icon-caret-right:before {\n  content: \"\";\n}\n\n.rst-versions {\n  position: fixed;\n  bottom: 0;\n  left: 0;\n  width: 300px;\n  color: #fcfcfc;\n  background: #1f1d1d;\n  border-top: solid 10px #343131;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  z-index: 400;\n}\n.rst-versions a {\n  color: #0E6FD2;\n  text-decoration: none;\n}\n.rst-versions .rst-badge-small {\n  display: none;\n}\n.rst-versions .rst-current-version {\n  padding: 12px;\n  background-color: #272525;\n  display: block;\n  text-align: right;\n  font-size: 90%;\n  cursor: pointer;\n  color: #27AE60;\n  *zoom: 1;\n}\n.rst-versions .rst-current-version:before, .rst-versions .rst-current-version:after {\n  display: table;\n  content: \"\";\n}\n.rst-versions .rst-current-version:after {\n  clear: both;\n}\n.rst-versions .rst-current-version .fa {\n  color: #fcfcfc;\n}\n.rst-versions .rst-current-version .fa-book {\n  float: left;\n}\n.rst-versions .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions .rst-current-version.rst-out-of-date {\n  background-color: #E74C3C;\n  color: #fff;\n}\n.rst-versions .rst-current-version.rst-active-old-version {\n  background-color: #F1C40F;\n  color: #000;\n}\n.rst-versions.shift-up .rst-other-versions {\n  display: block;\n}\n.rst-versions .rst-other-versions {\n  font-size: 90%;\n  padding: 12px;\n  color: gray;\n  display: none;\n}\n.rst-versions .rst-other-versions hr {\n  display: block;\n  height: 1px;\n  border: 0;\n  margin: 20px 0;\n  padding: 0;\n  border-top: solid 1px #413d3d;\n}\n.rst-versions .rst-other-versions dd {\n  display: inline-block;\n  margin: 0;\n}\n.rst-versions .rst-other-versions dd a {\n  display: inline-block;\n  padding: 6px;\n  color: #fcfcfc;\n}\n.rst-versions.rst-badge {\n  width: auto;\n  bottom: 20px;\n  right: 20px;\n  left: auto;\n  border: none;\n  max-width: 300px;\n}\n.rst-versions.rst-badge .icon-book {\n  float: none;\n}\n.rst-versions.rst-badge .fa-book {\n  float: none;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version {\n  text-align: right;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version .fa-book {\n  float: left;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions.rst-badge .rst-current-version {\n  width: auto;\n  height: 30px;\n  line-height: 30px;\n  padding: 0 6px;\n  display: block;\n  text-align: center;\n}\n\n@media screen and (max-width: 768px) {\n  .rst-versions {\n    width: 85%;\n    display: none;\n  }\n  .rst-versions.shift {\n    display: block;\n  }\n\n  img {\n    width: 100%;\n    height: auto;\n  }\n}\n\n/*# sourceMappingURL=badge_only.css.map */\n"
  },
  {
    "path": "docs/_static/css/theme.css",
    "content": "@charset \"UTF-8\";\n* {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n\narticle, aside, details, figcaption, figure, footer, header, hgroup, nav, section {\n  display: block;\n}\n\naudio, canvas, video {\n  display: inline-block;\n  *display: inline;\n  *zoom: 1;\n}\n\naudio:not([controls]) {\n  display: none;\n}\n\n[hidden] {\n  display: none;\n}\n\n* {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n\nhtml {\n  font-size: 100%;\n  -webkit-text-size-adjust: 100%;\n  -ms-text-size-adjust: 100%;\n}\n\nbody {\n  margin: 0;\n}\n\na:hover, a:active {\n  outline: 0;\n}\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\nb, strong {\n  font-weight: bold;\n}\n\nblockquote {\n  margin: 0;\n}\n\ndfn {\n  font-style: italic;\n}\n\nins {\n  background: #ff9;\n  color: #000;\n  text-decoration: none;\n}\n\nmark {\n  background: #ff0;\n  color: #000;\n  font-style: italic;\n  font-weight: bold;\n}\n\npre, code, .rst-content tt, .rst-content code, kbd, samp {\n  font-family: monospace, serif;\n  _font-family: \"courier new\", monospace;\n  font-size: 1em;\n}\n\npre {\n  white-space: pre;\n}\n\nq {\n  quotes: none;\n}\n\nq:before, q:after {\n  content: \"\";\n  content: none;\n}\n\nsmall {\n  font-size: 85%;\n}\n\nsub, sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nul, ol, dl {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n  list-style-image: none;\n}\n\nli {\n  list-style: none;\n}\n\ndd {\n  margin: 0;\n}\n\nimg {\n  border: 0;\n  -ms-interpolation-mode: bicubic;\n  vertical-align: middle;\n  max-width: 100%;\n}\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\nfigure {\n  margin: 0;\n}\n\nform {\n  margin: 0;\n}\n\nfieldset {\n  border: 0;\n  margin: 0;\n  padding: 0;\n}\n\nlabel {\n  cursor: pointer;\n}\n\nlegend {\n  border: 0;\n  *margin-left: -7px;\n  padding: 0;\n  white-space: normal;\n}\n\nbutton, input, select, textarea {\n  font-size: 100%;\n  margin: 0;\n  vertical-align: baseline;\n  *vertical-align: middle;\n}\n\nbutton, input {\n  line-height: normal;\n}\n\nbutton, input[type=\"button\"], input[type=\"reset\"], input[type=\"submit\"] {\n  cursor: pointer;\n  -webkit-appearance: button;\n  *overflow: visible;\n}\n\nbutton[disabled], input[disabled] {\n  cursor: default;\n}\n\ninput[type=\"checkbox\"], input[type=\"radio\"] {\n  box-sizing: border-box;\n  padding: 0;\n  *width: 13px;\n  *height: 13px;\n}\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield;\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\ninput[type=\"search\"]::-webkit-search-decoration, input[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\nbutton::-moz-focus-inner, input::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\ntextarea {\n  overflow: auto;\n  vertical-align: top;\n  resize: vertical;\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd {\n  vertical-align: top;\n}\n\n.chromeframe {\n  margin: 0.2em 0;\n  background: #ccc;\n  color: black;\n  padding: 0.2em 0;\n}\n\n.ir {\n  display: block;\n  border: 0;\n  text-indent: -999em;\n  overflow: hidden;\n  background-color: transparent;\n  background-repeat: no-repeat;\n  text-align: left;\n  direction: ltr;\n  *line-height: 0;\n}\n\n.ir br {\n  display: none;\n}\n\n.hidden {\n  display: none !important;\n  visibility: hidden;\n}\n\n.visuallyhidden {\n  border: 0;\n  clip: rect(0 0 0 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px;\n}\n\n.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus {\n  clip: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  position: static;\n  width: auto;\n}\n\n.invisible {\n  visibility: hidden;\n}\n\n.relative {\n  position: relative;\n}\n\nbig, small {\n  font-size: 100%;\n}\n\n@media print {\n  html, body, section {\n    background: none !important;\n  }\n\n  * {\n    box-shadow: none !important;\n    text-shadow: none !important;\n    filter: none !important;\n    -ms-filter: none !important;\n  }\n\n  a, a:visited {\n    text-decoration: underline;\n  }\n\n  .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  pre, blockquote {\n    page-break-inside: avoid;\n  }\n\n  thead {\n    display: table-header-group;\n  }\n\n  tr, img {\n    page-break-inside: avoid;\n  }\n\n  img {\n    max-width: 100% !important;\n  }\n\n  @page {\n    margin: 0.5cm;\n  }\n  p, h2, .rst-content .toctree-wrapper p.caption, h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  h2, .rst-content .toctree-wrapper p.caption, h3 {\n    page-break-after: avoid;\n  }\n}\n.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 {\n  -webkit-font-smoothing: antialiased;\n}\n\n.clearfix {\n  *zoom: 1;\n}\n.clearfix:before, .clearfix:after {\n  display: table;\n  content: \"\";\n}\n.clearfix:after {\n  clear: both;\n}\n\n/*!\n *  Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n/* FONT PATH\n * -------------------------- */\n@font-face {\n  font-family: 'FontAwesome';\n  src: url(\"../fonts/fontawesome-webfont.eot?v=4.2.0\");\n  src: url(\"../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0\") format(\"embedded-opentype\"), url(\"../fonts/fontawesome-webfont.woff?v=4.2.0\") format(\"woff\"), url(\"../fonts/fontawesome-webfont.ttf?v=4.2.0\") format(\"truetype\"), url(\"../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular\") format(\"svg\");\n  font-weight: normal;\n  font-style: normal;\n}\n.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 {\n  display: inline-block;\n  font: normal normal normal 14px/1 FontAwesome;\n  font-size: inherit;\n  text-rendering: auto;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n/* makes the font 33% larger relative to the icon container */\n.fa-lg {\n  font-size: 1.33333em;\n  line-height: 0.75em;\n  vertical-align: -15%;\n}\n\n.fa-2x {\n  font-size: 2em;\n}\n\n.fa-3x {\n  font-size: 3em;\n}\n\n.fa-4x {\n  font-size: 4em;\n}\n\n.fa-5x {\n  font-size: 5em;\n}\n\n.fa-fw {\n  width: 1.28571em;\n  text-align: center;\n}\n\n.fa-ul {\n  padding-left: 0;\n  margin-left: 2.14286em;\n  list-style-type: none;\n}\n.fa-ul > li {\n  position: relative;\n}\n\n.fa-li {\n  position: absolute;\n  left: -2.14286em;\n  width: 2.14286em;\n  top: 0.14286em;\n  text-align: center;\n}\n.fa-li.fa-lg {\n  left: -1.85714em;\n}\n\n.fa-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em #eee;\n  border-radius: .1em;\n}\n\n.pull-right {\n  float: right;\n}\n\n.pull-left {\n  float: left;\n}\n\n.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 {\n  margin-right: .3em;\n}\n.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 {\n  margin-left: .3em;\n}\n\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n  animation: fa-spin 2s infinite linear;\n}\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n.fa-rotate-90 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n  -webkit-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n\n.fa-rotate-180 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n\n.fa-rotate-270 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n  -webkit-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n\n.fa-flip-horizontal {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0);\n  -webkit-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n\n.fa-flip-vertical {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical {\n  filter: none;\n}\n\n.fa-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n\n.fa-stack-1x, .fa-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n\n.fa-stack-1x {\n  line-height: inherit;\n}\n\n.fa-stack-2x {\n  font-size: 2em;\n}\n\n.fa-inverse {\n  color: #fff;\n}\n\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.fa-glass:before {\n  content: \"\";\n}\n\n.fa-music:before {\n  content: \"\";\n}\n\n.fa-search:before, .icon-search:before {\n  content: \"\";\n}\n\n.fa-envelope-o:before {\n  content: \"\";\n}\n\n.fa-heart:before {\n  content: \"\";\n}\n\n.fa-star:before {\n  content: \"\";\n}\n\n.fa-star-o:before {\n  content: \"\";\n}\n\n.fa-user:before {\n  content: \"\";\n}\n\n.fa-film:before {\n  content: \"\";\n}\n\n.fa-th-large:before {\n  content: \"\";\n}\n\n.fa-th:before {\n  content: \"\";\n}\n\n.fa-th-list:before {\n  content: \"\";\n}\n\n.fa-check:before {\n  content: \"\";\n}\n\n.fa-remove:before,\n.fa-close:before,\n.fa-times:before {\n  content: \"\";\n}\n\n.fa-search-plus:before {\n  content: \"\";\n}\n\n.fa-search-minus:before {\n  content: \"\";\n}\n\n.fa-power-off:before {\n  content: \"\";\n}\n\n.fa-signal:before {\n  content: \"\";\n}\n\n.fa-gear:before,\n.fa-cog:before {\n  content: \"\";\n}\n\n.fa-trash-o:before {\n  content: \"\";\n}\n\n.fa-home:before, .icon-home:before {\n  content: \"\";\n}\n\n.fa-file-o:before {\n  content: \"\";\n}\n\n.fa-clock-o:before {\n  content: \"\";\n}\n\n.fa-road:before {\n  content: \"\";\n}\n\n.fa-download:before, .rst-content tt.download span:first-child:before, .rst-content code.download span:first-child:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-o-down:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-o-up:before {\n  content: \"\";\n}\n\n.fa-inbox:before {\n  content: \"\";\n}\n\n.fa-play-circle-o:before {\n  content: \"\";\n}\n\n.fa-rotate-right:before,\n.fa-repeat:before {\n  content: \"\";\n}\n\n.fa-refresh:before {\n  content: \"\";\n}\n\n.fa-list-alt:before {\n  content: \"\";\n}\n\n.fa-lock:before {\n  content: \"\";\n}\n\n.fa-flag:before {\n  content: \"\";\n}\n\n.fa-headphones:before {\n  content: \"\";\n}\n\n.fa-volume-off:before {\n  content: \"\";\n}\n\n.fa-volume-down:before {\n  content: \"\";\n}\n\n.fa-volume-up:before {\n  content: \"\";\n}\n\n.fa-qrcode:before {\n  content: \"\";\n}\n\n.fa-barcode:before {\n  content: \"\";\n}\n\n.fa-tag:before {\n  content: \"\";\n}\n\n.fa-tags:before {\n  content: \"\";\n}\n\n.fa-book:before, .icon-book:before {\n  content: \"\";\n}\n\n.fa-bookmark:before {\n  content: \"\";\n}\n\n.fa-print:before {\n  content: \"\";\n}\n\n.fa-camera:before {\n  content: \"\";\n}\n\n.fa-font:before {\n  content: \"\";\n}\n\n.fa-bold:before {\n  content: \"\";\n}\n\n.fa-italic:before {\n  content: \"\";\n}\n\n.fa-text-height:before {\n  content: \"\";\n}\n\n.fa-text-width:before {\n  content: \"\";\n}\n\n.fa-align-left:before {\n  content: \"\";\n}\n\n.fa-align-center:before {\n  content: \"\";\n}\n\n.fa-align-right:before {\n  content: \"\";\n}\n\n.fa-align-justify:before {\n  content: \"\";\n}\n\n.fa-list:before {\n  content: \"\";\n}\n\n.fa-dedent:before,\n.fa-outdent:before {\n  content: \"\";\n}\n\n.fa-indent:before {\n  content: \"\";\n}\n\n.fa-video-camera:before {\n  content: \"\";\n}\n\n.fa-photo:before,\n.fa-image:before,\n.fa-picture-o:before {\n  content: \"\";\n}\n\n.fa-pencil:before {\n  content: \"\";\n}\n\n.fa-map-marker:before {\n  content: \"\";\n}\n\n.fa-adjust:before {\n  content: \"\";\n}\n\n.fa-tint:before {\n  content: \"\";\n}\n\n.fa-edit:before,\n.fa-pencil-square-o:before {\n  content: \"\";\n}\n\n.fa-share-square-o:before {\n  content: \"\";\n}\n\n.fa-check-square-o:before {\n  content: \"\";\n}\n\n.fa-arrows:before {\n  content: \"\";\n}\n\n.fa-step-backward:before {\n  content: \"\";\n}\n\n.fa-fast-backward:before {\n  content: \"\";\n}\n\n.fa-backward:before {\n  content: \"\";\n}\n\n.fa-play:before {\n  content: \"\";\n}\n\n.fa-pause:before {\n  content: \"\";\n}\n\n.fa-stop:before {\n  content: \"\";\n}\n\n.fa-forward:before {\n  content: \"\";\n}\n\n.fa-fast-forward:before {\n  content: \"\";\n}\n\n.fa-step-forward:before {\n  content: \"\";\n}\n\n.fa-eject:before {\n  content: \"\";\n}\n\n.fa-chevron-left:before {\n  content: \"\";\n}\n\n.fa-chevron-right:before {\n  content: \"\";\n}\n\n.fa-plus-circle:before {\n  content: \"\";\n}\n\n.fa-minus-circle:before {\n  content: \"\";\n}\n\n.fa-times-circle:before, .wy-inline-validate.wy-inline-validate-danger .wy-input-context:before {\n  content: \"\";\n}\n\n.fa-check-circle:before, .wy-inline-validate.wy-inline-validate-success .wy-input-context:before {\n  content: \"\";\n}\n\n.fa-question-circle:before {\n  content: \"\";\n}\n\n.fa-info-circle:before {\n  content: \"\";\n}\n\n.fa-crosshairs:before {\n  content: \"\";\n}\n\n.fa-times-circle-o:before {\n  content: \"\";\n}\n\n.fa-check-circle-o:before {\n  content: \"\";\n}\n\n.fa-ban:before {\n  content: \"\";\n}\n\n.fa-arrow-left:before {\n  content: \"\";\n}\n\n.fa-arrow-right:before {\n  content: \"\";\n}\n\n.fa-arrow-up:before {\n  content: \"\";\n}\n\n.fa-arrow-down:before {\n  content: \"\";\n}\n\n.fa-mail-forward:before,\n.fa-share:before {\n  content: \"\";\n}\n\n.fa-expand:before {\n  content: \"\";\n}\n\n.fa-compress:before {\n  content: \"\";\n}\n\n.fa-plus:before {\n  content: \"\";\n}\n\n.fa-minus:before {\n  content: \"\";\n}\n\n.fa-asterisk:before {\n  content: \"\";\n}\n\n.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 {\n  content: \"\";\n}\n\n.fa-gift:before {\n  content: \"\";\n}\n\n.fa-leaf:before {\n  content: \"\";\n}\n\n.fa-fire:before, .icon-fire:before {\n  content: \"\";\n}\n\n.fa-eye:before {\n  content: \"\";\n}\n\n.fa-eye-slash:before {\n  content: \"\";\n}\n\n.fa-warning:before,\n.fa-exclamation-triangle:before {\n  content: \"\";\n}\n\n.fa-plane:before {\n  content: \"\";\n}\n\n.fa-calendar:before {\n  content: \"\";\n}\n\n.fa-random:before {\n  content: \"\";\n}\n\n.fa-comment:before {\n  content: \"\";\n}\n\n.fa-magnet:before {\n  content: \"\";\n}\n\n.fa-chevron-up:before {\n  content: \"\";\n}\n\n.fa-chevron-down:before {\n  content: \"\";\n}\n\n.fa-retweet:before {\n  content: \"\";\n}\n\n.fa-shopping-cart:before {\n  content: \"\";\n}\n\n.fa-folder:before {\n  content: \"\";\n}\n\n.fa-folder-open:before {\n  content: \"\";\n}\n\n.fa-arrows-v:before {\n  content: \"\";\n}\n\n.fa-arrows-h:before {\n  content: \"\";\n}\n\n.fa-bar-chart-o:before,\n.fa-bar-chart:before {\n  content: \"\";\n}\n\n.fa-twitter-square:before {\n  content: \"\";\n}\n\n.fa-facebook-square:before {\n  content: \"\";\n}\n\n.fa-camera-retro:before {\n  content: \"\";\n}\n\n.fa-key:before {\n  content: \"\";\n}\n\n.fa-gears:before,\n.fa-cogs:before {\n  content: \"\";\n}\n\n.fa-comments:before {\n  content: \"\";\n}\n\n.fa-thumbs-o-up:before {\n  content: \"\";\n}\n\n.fa-thumbs-o-down:before {\n  content: \"\";\n}\n\n.fa-star-half:before {\n  content: \"\";\n}\n\n.fa-heart-o:before {\n  content: \"\";\n}\n\n.fa-sign-out:before {\n  content: \"\";\n}\n\n.fa-linkedin-square:before {\n  content: \"\";\n}\n\n.fa-thumb-tack:before {\n  content: \"\";\n}\n\n.fa-external-link:before {\n  content: \"\";\n}\n\n.fa-sign-in:before {\n  content: \"\";\n}\n\n.fa-trophy:before {\n  content: \"\";\n}\n\n.fa-github-square:before {\n  content: \"\";\n}\n\n.fa-upload:before {\n  content: \"\";\n}\n\n.fa-lemon-o:before {\n  content: \"\";\n}\n\n.fa-phone:before {\n  content: \"\";\n}\n\n.fa-square-o:before {\n  content: \"\";\n}\n\n.fa-bookmark-o:before {\n  content: \"\";\n}\n\n.fa-phone-square:before {\n  content: \"\";\n}\n\n.fa-twitter:before {\n  content: \"\";\n}\n\n.fa-facebook:before {\n  content: \"\";\n}\n\n.fa-github:before, .icon-github:before {\n  content: \"\";\n}\n\n.fa-unlock:before {\n  content: \"\";\n}\n\n.fa-credit-card:before {\n  content: \"\";\n}\n\n.fa-rss:before {\n  content: \"\";\n}\n\n.fa-hdd-o:before {\n  content: \"\";\n}\n\n.fa-bullhorn:before {\n  content: \"\";\n}\n\n.fa-bell:before {\n  content: \"\";\n}\n\n.fa-certificate:before {\n  content: \"\";\n}\n\n.fa-hand-o-right:before {\n  content: \"\";\n}\n\n.fa-hand-o-left:before {\n  content: \"\";\n}\n\n.fa-hand-o-up:before {\n  content: \"\";\n}\n\n.fa-hand-o-down:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-left:before, .icon-circle-arrow-left:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-right:before, .icon-circle-arrow-right:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-up:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-down:before {\n  content: \"\";\n}\n\n.fa-globe:before {\n  content: \"\";\n}\n\n.fa-wrench:before {\n  content: \"\";\n}\n\n.fa-tasks:before {\n  content: \"\";\n}\n\n.fa-filter:before {\n  content: \"\";\n}\n\n.fa-briefcase:before {\n  content: \"\";\n}\n\n.fa-arrows-alt:before {\n  content: \"\";\n}\n\n.fa-group:before,\n.fa-users:before {\n  content: \"\";\n}\n\n.fa-chain:before,\n.fa-link:before,\n.icon-link:before {\n  content: \"\";\n}\n\n.fa-cloud:before {\n  content: \"\";\n}\n\n.fa-flask:before {\n  content: \"\";\n}\n\n.fa-cut:before,\n.fa-scissors:before {\n  content: \"\";\n}\n\n.fa-copy:before,\n.fa-files-o:before {\n  content: \"\";\n}\n\n.fa-paperclip:before {\n  content: \"\";\n}\n\n.fa-save:before,\n.fa-floppy-o:before {\n  content: \"\";\n}\n\n.fa-square:before {\n  content: \"\";\n}\n\n.fa-navicon:before,\n.fa-reorder:before,\n.fa-bars:before {\n  content: \"\";\n}\n\n.fa-list-ul:before {\n  content: \"\";\n}\n\n.fa-list-ol:before {\n  content: \"\";\n}\n\n.fa-strikethrough:before {\n  content: \"\";\n}\n\n.fa-underline:before {\n  content: \"\";\n}\n\n.fa-table:before {\n  content: \"\";\n}\n\n.fa-magic:before {\n  content: \"\";\n}\n\n.fa-truck:before {\n  content: \"\";\n}\n\n.fa-pinterest:before {\n  content: \"\";\n}\n\n.fa-pinterest-square:before {\n  content: \"\";\n}\n\n.fa-google-plus-square:before {\n  content: \"\";\n}\n\n.fa-google-plus:before {\n  content: \"\";\n}\n\n.fa-money:before {\n  content: \"\";\n}\n\n.fa-caret-down:before, .wy-dropdown .caret:before, .icon-caret-down:before {\n  content: \"\";\n}\n\n.fa-caret-up:before {\n  content: \"\";\n}\n\n.fa-caret-left:before {\n  content: \"\";\n}\n\n.fa-caret-right:before {\n  content: \"\";\n}\n\n.fa-columns:before {\n  content: \"\";\n}\n\n.fa-unsorted:before,\n.fa-sort:before {\n  content: \"\";\n}\n\n.fa-sort-down:before,\n.fa-sort-desc:before {\n  content: \"\";\n}\n\n.fa-sort-up:before,\n.fa-sort-asc:before {\n  content: \"\";\n}\n\n.fa-envelope:before {\n  content: \"\";\n}\n\n.fa-linkedin:before {\n  content: \"\";\n}\n\n.fa-rotate-left:before,\n.fa-undo:before {\n  content: \"\";\n}\n\n.fa-legal:before,\n.fa-gavel:before {\n  content: \"\";\n}\n\n.fa-dashboard:before,\n.fa-tachometer:before {\n  content: \"\";\n}\n\n.fa-comment-o:before {\n  content: \"\";\n}\n\n.fa-comments-o:before {\n  content: \"\";\n}\n\n.fa-flash:before,\n.fa-bolt:before {\n  content: \"\";\n}\n\n.fa-sitemap:before {\n  content: \"\";\n}\n\n.fa-umbrella:before {\n  content: \"\";\n}\n\n.fa-paste:before,\n.fa-clipboard:before {\n  content: \"\";\n}\n\n.fa-lightbulb-o:before {\n  content: \"\";\n}\n\n.fa-exchange:before {\n  content: \"\";\n}\n\n.fa-cloud-download:before {\n  content: \"\";\n}\n\n.fa-cloud-upload:before {\n  content: \"\";\n}\n\n.fa-user-md:before {\n  content: \"\";\n}\n\n.fa-stethoscope:before {\n  content: \"\";\n}\n\n.fa-suitcase:before {\n  content: \"\";\n}\n\n.fa-bell-o:before {\n  content: \"\";\n}\n\n.fa-coffee:before {\n  content: \"\";\n}\n\n.fa-cutlery:before {\n  content: \"\";\n}\n\n.fa-file-text-o:before {\n  content: \"\";\n}\n\n.fa-building-o:before {\n  content: \"\";\n}\n\n.fa-hospital-o:before {\n  content: \"\";\n}\n\n.fa-ambulance:before {\n  content: \"\";\n}\n\n.fa-medkit:before {\n  content: \"\";\n}\n\n.fa-fighter-jet:before {\n  content: \"\";\n}\n\n.fa-beer:before {\n  content: \"\";\n}\n\n.fa-h-square:before {\n  content: \"\";\n}\n\n.fa-plus-square:before {\n  content: \"\";\n}\n\n.fa-angle-double-left:before {\n  content: \"\";\n}\n\n.fa-angle-double-right:before {\n  content: \"\";\n}\n\n.fa-angle-double-up:before {\n  content: \"\";\n}\n\n.fa-angle-double-down:before {\n  content: \"\";\n}\n\n.fa-angle-left:before {\n  content: \"\";\n}\n\n.fa-angle-right:before {\n  content: \"\";\n}\n\n.fa-angle-up:before {\n  content: \"\";\n}\n\n.fa-angle-down:before {\n  content: \"\";\n}\n\n.fa-desktop:before {\n  content: \"\";\n}\n\n.fa-laptop:before {\n  content: \"\";\n}\n\n.fa-tablet:before {\n  content: \"\";\n}\n\n.fa-mobile-phone:before,\n.fa-mobile:before {\n  content: \"\";\n}\n\n.fa-circle-o:before {\n  content: \"\";\n}\n\n.fa-quote-left:before {\n  content: \"\";\n}\n\n.fa-quote-right:before {\n  content: \"\";\n}\n\n.fa-spinner:before {\n  content: \"\";\n}\n\n.fa-circle:before {\n  content: \"\";\n}\n\n.fa-mail-reply:before,\n.fa-reply:before {\n  content: \"\";\n}\n\n.fa-github-alt:before {\n  content: \"\";\n}\n\n.fa-folder-o:before {\n  content: \"\";\n}\n\n.fa-folder-open-o:before {\n  content: \"\";\n}\n\n.fa-smile-o:before {\n  content: \"\";\n}\n\n.fa-frown-o:before {\n  content: \"\";\n}\n\n.fa-meh-o:before {\n  content: \"\";\n}\n\n.fa-gamepad:before {\n  content: \"\";\n}\n\n.fa-keyboard-o:before {\n  content: \"\";\n}\n\n.fa-flag-o:before {\n  content: \"\";\n}\n\n.fa-flag-checkered:before {\n  content: \"\";\n}\n\n.fa-terminal:before {\n  content: \"\";\n}\n\n.fa-code:before {\n  content: \"\";\n}\n\n.fa-mail-reply-all:before,\n.fa-reply-all:before {\n  content: \"\";\n}\n\n.fa-star-half-empty:before,\n.fa-star-half-full:before,\n.fa-star-half-o:before {\n  content: \"\";\n}\n\n.fa-location-arrow:before {\n  content: \"\";\n}\n\n.fa-crop:before {\n  content: \"\";\n}\n\n.fa-code-fork:before {\n  content: \"\";\n}\n\n.fa-unlink:before,\n.fa-chain-broken:before {\n  content: \"\";\n}\n\n.fa-question:before {\n  content: \"\";\n}\n\n.fa-info:before {\n  content: \"\";\n}\n\n.fa-exclamation:before {\n  content: \"\";\n}\n\n.fa-superscript:before {\n  content: \"\";\n}\n\n.fa-subscript:before {\n  content: \"\";\n}\n\n.fa-eraser:before {\n  content: \"\";\n}\n\n.fa-puzzle-piece:before {\n  content: \"\";\n}\n\n.fa-microphone:before {\n  content: \"\";\n}\n\n.fa-microphone-slash:before {\n  content: \"\";\n}\n\n.fa-shield:before {\n  content: \"\";\n}\n\n.fa-calendar-o:before {\n  content: \"\";\n}\n\n.fa-fire-extinguisher:before {\n  content: \"\";\n}\n\n.fa-rocket:before {\n  content: \"\";\n}\n\n.fa-maxcdn:before {\n  content: \"\";\n}\n\n.fa-chevron-circle-left:before {\n  content: \"\";\n}\n\n.fa-chevron-circle-right:before {\n  content: \"\";\n}\n\n.fa-chevron-circle-up:before {\n  content: \"\";\n}\n\n.fa-chevron-circle-down:before {\n  content: \"\";\n}\n\n.fa-html5:before {\n  content: \"\";\n}\n\n.fa-css3:before {\n  content: \"\";\n}\n\n.fa-anchor:before {\n  content: \"\";\n}\n\n.fa-unlock-alt:before {\n  content: \"\";\n}\n\n.fa-bullseye:before {\n  content: \"\";\n}\n\n.fa-ellipsis-h:before {\n  content: \"\";\n}\n\n.fa-ellipsis-v:before {\n  content: \"\";\n}\n\n.fa-rss-square:before {\n  content: \"\";\n}\n\n.fa-play-circle:before {\n  content: \"\";\n}\n\n.fa-ticket:before {\n  content: \"\";\n}\n\n.fa-minus-square:before {\n  content: \"\";\n}\n\n.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 {\n  content: \"\";\n}\n\n.fa-level-up:before {\n  content: \"\";\n}\n\n.fa-level-down:before {\n  content: \"\";\n}\n\n.fa-check-square:before {\n  content: \"\";\n}\n\n.fa-pencil-square:before {\n  content: \"\";\n}\n\n.fa-external-link-square:before {\n  content: \"\";\n}\n\n.fa-share-square:before {\n  content: \"\";\n}\n\n.fa-compass:before {\n  content: \"\";\n}\n\n.fa-toggle-down:before,\n.fa-caret-square-o-down:before {\n  content: \"\";\n}\n\n.fa-toggle-up:before,\n.fa-caret-square-o-up:before {\n  content: \"\";\n}\n\n.fa-toggle-right:before,\n.fa-caret-square-o-right:before {\n  content: \"\";\n}\n\n.fa-euro:before,\n.fa-eur:before {\n  content: \"\";\n}\n\n.fa-gbp:before {\n  content: \"\";\n}\n\n.fa-dollar:before,\n.fa-usd:before {\n  content: \"\";\n}\n\n.fa-rupee:before,\n.fa-inr:before {\n  content: \"\";\n}\n\n.fa-cny:before,\n.fa-rmb:before,\n.fa-yen:before,\n.fa-jpy:before {\n  content: \"\";\n}\n\n.fa-ruble:before,\n.fa-rouble:before,\n.fa-rub:before {\n  content: \"\";\n}\n\n.fa-won:before,\n.fa-krw:before {\n  content: \"\";\n}\n\n.fa-bitcoin:before,\n.fa-btc:before {\n  content: \"\";\n}\n\n.fa-file:before {\n  content: \"\";\n}\n\n.fa-file-text:before {\n  content: \"\";\n}\n\n.fa-sort-alpha-asc:before {\n  content: \"\";\n}\n\n.fa-sort-alpha-desc:before {\n  content: \"\";\n}\n\n.fa-sort-amount-asc:before {\n  content: \"\";\n}\n\n.fa-sort-amount-desc:before {\n  content: \"\";\n}\n\n.fa-sort-numeric-asc:before {\n  content: \"\";\n}\n\n.fa-sort-numeric-desc:before {\n  content: \"\";\n}\n\n.fa-thumbs-up:before {\n  content: \"\";\n}\n\n.fa-thumbs-down:before {\n  content: \"\";\n}\n\n.fa-youtube-square:before {\n  content: \"\";\n}\n\n.fa-youtube:before {\n  content: \"\";\n}\n\n.fa-xing:before {\n  content: \"\";\n}\n\n.fa-xing-square:before {\n  content: \"\";\n}\n\n.fa-youtube-play:before {\n  content: \"\";\n}\n\n.fa-dropbox:before {\n  content: \"\";\n}\n\n.fa-stack-overflow:before {\n  content: \"\";\n}\n\n.fa-instagram:before {\n  content: \"\";\n}\n\n.fa-flickr:before {\n  content: \"\";\n}\n\n.fa-adn:before {\n  content: \"\";\n}\n\n.fa-bitbucket:before, .icon-bitbucket:before {\n  content: \"\";\n}\n\n.fa-bitbucket-square:before {\n  content: \"\";\n}\n\n.fa-tumblr:before {\n  content: \"\";\n}\n\n.fa-tumblr-square:before {\n  content: \"\";\n}\n\n.fa-long-arrow-down:before {\n  content: \"\";\n}\n\n.fa-long-arrow-up:before {\n  content: \"\";\n}\n\n.fa-long-arrow-left:before {\n  content: \"\";\n}\n\n.fa-long-arrow-right:before {\n  content: \"\";\n}\n\n.fa-apple:before {\n  content: \"\";\n}\n\n.fa-windows:before {\n  content: \"\";\n}\n\n.fa-android:before {\n  content: \"\";\n}\n\n.fa-linux:before {\n  content: \"\";\n}\n\n.fa-dribbble:before {\n  content: \"\";\n}\n\n.fa-skype:before {\n  content: \"\";\n}\n\n.fa-foursquare:before {\n  content: \"\";\n}\n\n.fa-trello:before {\n  content: \"\";\n}\n\n.fa-female:before {\n  content: \"\";\n}\n\n.fa-male:before {\n  content: \"\";\n}\n\n.fa-gittip:before {\n  content: \"\";\n}\n\n.fa-sun-o:before {\n  content: \"\";\n}\n\n.fa-moon-o:before {\n  content: \"\";\n}\n\n.fa-archive:before {\n  content: \"\";\n}\n\n.fa-bug:before {\n  content: \"\";\n}\n\n.fa-vk:before {\n  content: \"\";\n}\n\n.fa-weibo:before {\n  content: \"\";\n}\n\n.fa-renren:before {\n  content: \"\";\n}\n\n.fa-pagelines:before {\n  content: \"\";\n}\n\n.fa-stack-exchange:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-o-right:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-o-left:before {\n  content: \"\";\n}\n\n.fa-toggle-left:before,\n.fa-caret-square-o-left:before {\n  content: \"\";\n}\n\n.fa-dot-circle-o:before {\n  content: \"\";\n}\n\n.fa-wheelchair:before {\n  content: \"\";\n}\n\n.fa-vimeo-square:before {\n  content: \"\";\n}\n\n.fa-turkish-lira:before,\n.fa-try:before {\n  content: \"\";\n}\n\n.fa-plus-square-o:before, .wy-menu-vertical li span.toctree-expand:before {\n  content: \"\";\n}\n\n.fa-space-shuttle:before {\n  content: \"\";\n}\n\n.fa-slack:before {\n  content: \"\";\n}\n\n.fa-envelope-square:before {\n  content: \"\";\n}\n\n.fa-wordpress:before {\n  content: \"\";\n}\n\n.fa-openid:before {\n  content: \"\";\n}\n\n.fa-institution:before,\n.fa-bank:before,\n.fa-university:before {\n  content: \"\";\n}\n\n.fa-mortar-board:before,\n.fa-graduation-cap:before {\n  content: \"\";\n}\n\n.fa-yahoo:before {\n  content: \"\";\n}\n\n.fa-google:before {\n  content: \"\";\n}\n\n.fa-reddit:before {\n  content: \"\";\n}\n\n.fa-reddit-square:before {\n  content: \"\";\n}\n\n.fa-stumbleupon-circle:before {\n  content: \"\";\n}\n\n.fa-stumbleupon:before {\n  content: \"\";\n}\n\n.fa-delicious:before {\n  content: \"\";\n}\n\n.fa-digg:before {\n  content: \"\";\n}\n\n.fa-pied-piper:before {\n  content: \"\";\n}\n\n.fa-pied-piper-alt:before {\n  content: \"\";\n}\n\n.fa-drupal:before {\n  content: \"\";\n}\n\n.fa-joomla:before {\n  content: \"\";\n}\n\n.fa-language:before {\n  content: \"\";\n}\n\n.fa-fax:before {\n  content: \"\";\n}\n\n.fa-building:before {\n  content: \"\";\n}\n\n.fa-child:before {\n  content: \"\";\n}\n\n.fa-paw:before {\n  content: \"\";\n}\n\n.fa-spoon:before {\n  content: \"\";\n}\n\n.fa-cube:before {\n  content: \"\";\n}\n\n.fa-cubes:before {\n  content: \"\";\n}\n\n.fa-behance:before {\n  content: \"\";\n}\n\n.fa-behance-square:before {\n  content: \"\";\n}\n\n.fa-steam:before {\n  content: \"\";\n}\n\n.fa-steam-square:before {\n  content: \"\";\n}\n\n.fa-recycle:before {\n  content: \"\";\n}\n\n.fa-automobile:before,\n.fa-car:before {\n  content: \"\";\n}\n\n.fa-cab:before,\n.fa-taxi:before {\n  content: \"\";\n}\n\n.fa-tree:before {\n  content: \"\";\n}\n\n.fa-spotify:before {\n  content: \"\";\n}\n\n.fa-deviantart:before {\n  content: \"\";\n}\n\n.fa-soundcloud:before {\n  content: \"\";\n}\n\n.fa-database:before {\n  content: \"\";\n}\n\n.fa-file-pdf-o:before {\n  content: \"\";\n}\n\n.fa-file-word-o:before {\n  content: \"\";\n}\n\n.fa-file-excel-o:before {\n  content: \"\";\n}\n\n.fa-file-powerpoint-o:before {\n  content: \"\";\n}\n\n.fa-file-photo-o:before,\n.fa-file-picture-o:before,\n.fa-file-image-o:before {\n  content: \"\";\n}\n\n.fa-file-zip-o:before,\n.fa-file-archive-o:before {\n  content: \"\";\n}\n\n.fa-file-sound-o:before,\n.fa-file-audio-o:before {\n  content: \"\";\n}\n\n.fa-file-movie-o:before,\n.fa-file-video-o:before {\n  content: \"\";\n}\n\n.fa-file-code-o:before {\n  content: \"\";\n}\n\n.fa-vine:before {\n  content: \"\";\n}\n\n.fa-codepen:before {\n  content: \"\";\n}\n\n.fa-jsfiddle:before {\n  content: \"\";\n}\n\n.fa-life-bouy:before,\n.fa-life-buoy:before,\n.fa-life-saver:before,\n.fa-support:before,\n.fa-life-ring:before {\n  content: \"\";\n}\n\n.fa-circle-o-notch:before {\n  content: \"\";\n}\n\n.fa-ra:before,\n.fa-rebel:before {\n  content: \"\";\n}\n\n.fa-ge:before,\n.fa-empire:before {\n  content: \"\";\n}\n\n.fa-git-square:before {\n  content: \"\";\n}\n\n.fa-git:before {\n  content: \"\";\n}\n\n.fa-hacker-news:before {\n  content: \"\";\n}\n\n.fa-tencent-weibo:before {\n  content: \"\";\n}\n\n.fa-qq:before {\n  content: \"\";\n}\n\n.fa-wechat:before,\n.fa-weixin:before {\n  content: \"\";\n}\n\n.fa-send:before,\n.fa-paper-plane:before {\n  content: \"\";\n}\n\n.fa-send-o:before,\n.fa-paper-plane-o:before {\n  content: \"\";\n}\n\n.fa-history:before {\n  content: \"\";\n}\n\n.fa-circle-thin:before {\n  content: \"\";\n}\n\n.fa-header:before {\n  content: \"\";\n}\n\n.fa-paragraph:before {\n  content: \"\";\n}\n\n.fa-sliders:before {\n  content: \"\";\n}\n\n.fa-share-alt:before {\n  content: \"\";\n}\n\n.fa-share-alt-square:before {\n  content: \"\";\n}\n\n.fa-bomb:before {\n  content: \"\";\n}\n\n.fa-soccer-ball-o:before,\n.fa-futbol-o:before {\n  content: \"\";\n}\n\n.fa-tty:before {\n  content: \"\";\n}\n\n.fa-binoculars:before {\n  content: \"\";\n}\n\n.fa-plug:before {\n  content: \"\";\n}\n\n.fa-slideshare:before {\n  content: \"\";\n}\n\n.fa-twitch:before {\n  content: \"\";\n}\n\n.fa-yelp:before {\n  content: \"\";\n}\n\n.fa-newspaper-o:before {\n  content: \"\";\n}\n\n.fa-wifi:before {\n  content: \"\";\n}\n\n.fa-calculator:before {\n  content: \"\";\n}\n\n.fa-paypal:before {\n  content: \"\";\n}\n\n.fa-google-wallet:before {\n  content: \"\";\n}\n\n.fa-cc-visa:before {\n  content: \"\";\n}\n\n.fa-cc-mastercard:before {\n  content: \"\";\n}\n\n.fa-cc-discover:before {\n  content: \"\";\n}\n\n.fa-cc-amex:before {\n  content: \"\";\n}\n\n.fa-cc-paypal:before {\n  content: \"\";\n}\n\n.fa-cc-stripe:before {\n  content: \"\";\n}\n\n.fa-bell-slash:before {\n  content: \"\";\n}\n\n.fa-bell-slash-o:before {\n  content: \"\";\n}\n\n.fa-trash:before {\n  content: \"\";\n}\n\n.fa-copyright:before {\n  content: \"\";\n}\n\n.fa-at:before {\n  content: \"\";\n}\n\n.fa-eyedropper:before {\n  content: \"\";\n}\n\n.fa-paint-brush:before {\n  content: \"\";\n}\n\n.fa-birthday-cake:before {\n  content: \"\";\n}\n\n.fa-area-chart:before {\n  content: \"\";\n}\n\n.fa-pie-chart:before {\n  content: \"\";\n}\n\n.fa-line-chart:before {\n  content: \"\";\n}\n\n.fa-lastfm:before {\n  content: \"\";\n}\n\n.fa-lastfm-square:before {\n  content: \"\";\n}\n\n.fa-toggle-off:before {\n  content: \"\";\n}\n\n.fa-toggle-on:before {\n  content: \"\";\n}\n\n.fa-bicycle:before {\n  content: \"\";\n}\n\n.fa-bus:before {\n  content: \"\";\n}\n\n.fa-ioxhost:before {\n  content: \"\";\n}\n\n.fa-angellist:before {\n  content: \"\";\n}\n\n.fa-cc:before {\n  content: \"\";\n}\n\n.fa-shekel:before,\n.fa-sheqel:before,\n.fa-ils:before {\n  content: \"\";\n}\n\n.fa-meanpath:before {\n  content: \"\";\n}\n\n.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 {\n  font-family: inherit;\n}\n.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 {\n  font-family: \"FontAwesome\";\n  display: inline-block;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  text-decoration: inherit;\n}\n\na .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 {\n  display: inline-block;\n  text-decoration: inherit;\n}\n\n.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 {\n  display: inline;\n}\n.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 {\n  line-height: 0.9em;\n}\n.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 {\n  display: inline-block;\n}\n\n.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 {\n  opacity: 0.5;\n  -webkit-transition: opacity 0.05s ease-in;\n  -moz-transition: opacity 0.05s ease-in;\n  transition: opacity 0.05s ease-in;\n}\n\n.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 {\n  opacity: 1;\n}\n\n.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 {\n  font-size: 14px;\n  vertical-align: -15%;\n}\n\n.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 {\n  padding: 12px;\n  line-height: 24px;\n  margin-bottom: 24px;\n  background: #e2effd;\n}\n\n.wy-alert-title, .rst-content .admonition-title {\n  color: #fff;\n  font-weight: bold;\n  display: block;\n  color: #fff;\n  background: #53a2f4;\n  margin: -12px;\n  padding: 6px 12px;\n  margin-bottom: 12px;\n}\n\n.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 {\n  background: #fdf3f2;\n}\n.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 {\n  background: #f29f97;\n}\n\n.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 {\n  background: #ffedcc;\n}\n.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 {\n  background: #f0b37e;\n}\n\n.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 {\n  background: #e2effd;\n}\n.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 {\n  background: #53a2f4;\n}\n\n.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 {\n  background: #dbfaf4;\n}\n.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 {\n  background: #1abc9c;\n}\n\n.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 {\n  background: #f3f6f6;\n}\n.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 {\n  color: #404040;\n  background: #e1e4e5;\n}\n.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 {\n  color: #0E6FD2;\n}\n\n.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 {\n  margin-bottom: 0;\n}\n\n.wy-tray-container {\n  position: fixed;\n  bottom: 0px;\n  left: 0;\n  z-index: 600;\n}\n.wy-tray-container li {\n  display: block;\n  width: 300px;\n  background: transparent;\n  color: #fff;\n  text-align: center;\n  box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.1);\n  padding: 0 24px;\n  min-width: 20%;\n  opacity: 0;\n  height: 0;\n  line-height: 56px;\n  overflow: hidden;\n  -webkit-transition: all 0.3s ease-in;\n  -moz-transition: all 0.3s ease-in;\n  transition: all 0.3s ease-in;\n}\n.wy-tray-container li.wy-tray-item-success {\n  background: #27AE60;\n}\n.wy-tray-container li.wy-tray-item-info {\n  background: #0E6FD2;\n}\n.wy-tray-container li.wy-tray-item-warning {\n  background: #E67E22;\n}\n.wy-tray-container li.wy-tray-item-danger {\n  background: #E74C3C;\n}\n.wy-tray-container li.on {\n  opacity: 1;\n  height: 56px;\n}\n\n@media screen and (max-width: 768px) {\n  .wy-tray-container {\n    bottom: auto;\n    top: 0;\n    width: 100%;\n  }\n  .wy-tray-container li {\n    width: 100%;\n  }\n}\nbutton {\n  font-size: 100%;\n  margin: 0;\n  vertical-align: baseline;\n  *vertical-align: middle;\n  cursor: pointer;\n  line-height: normal;\n  -webkit-appearance: button;\n  *overflow: visible;\n}\n\nbutton::-moz-focus-inner, input::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\nbutton[disabled] {\n  cursor: default;\n}\n\n.btn {\n  /* Structure */\n  display: inline-block;\n  border-radius: 2px;\n  line-height: normal;\n  white-space: nowrap;\n  text-align: center;\n  cursor: pointer;\n  font-size: 100%;\n  padding: 6px 12px 8px 12px;\n  color: #fff;\n  border: 1px solid rgba(0, 0, 0, 0.1);\n  background-color: #27AE60;\n  text-decoration: none;\n  font-weight: normal;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  box-shadow: 0px 1px 2px -1px rgba(255, 255, 255, 0.5) inset, 0px -2px 0px 0px rgba(0, 0, 0, 0.1) inset;\n  outline-none: false;\n  vertical-align: middle;\n  *display: inline;\n  zoom: 1;\n  -webkit-user-drag: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  -webkit-transition: all 0.1s linear;\n  -moz-transition: all 0.1s linear;\n  transition: all 0.1s linear;\n}\n\n.btn-hover {\n  background: #107cea;\n  color: #fff;\n}\n\n.btn:hover {\n  background: #2cc36b;\n  color: #fff;\n}\n.btn:focus {\n  background: #2cc36b;\n  outline: 0;\n}\n.btn:active {\n  box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.05) inset, 0px 2px 0px 0px rgba(0, 0, 0, 0.1) inset;\n  padding: 8px 12px 6px 12px;\n}\n.btn:visited {\n  color: #fff;\n}\n.btn:disabled {\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  filter: alpha(opacity=40);\n  opacity: 0.4;\n  cursor: not-allowed;\n  box-shadow: none;\n}\n\n.btn-disabled {\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  filter: alpha(opacity=40);\n  opacity: 0.4;\n  cursor: not-allowed;\n  box-shadow: none;\n}\n.btn-disabled:hover, .btn-disabled:focus, .btn-disabled:active {\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  filter: alpha(opacity=40);\n  opacity: 0.4;\n  cursor: not-allowed;\n  box-shadow: none;\n}\n\n.btn::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\n\n.btn-small {\n  font-size: 80%;\n}\n\n.btn-info {\n  background-color: #0E6FD2 !important;\n}\n.btn-info:hover {\n  background-color: #107cea !important;\n}\n\n.btn-neutral {\n  background-color: #f3f6f6 !important;\n  color: #404040 !important;\n}\n.btn-neutral:hover {\n  background-color: #e5ebeb !important;\n  color: #404040;\n}\n.btn-neutral:visited {\n  color: #404040 !important;\n}\n\n.btn-success {\n  background-color: #27AE60 !important;\n}\n.btn-success:hover {\n  background-color: #229955 !important;\n}\n\n.btn-danger {\n  background-color: #E74C3C !important;\n}\n.btn-danger:hover {\n  background-color: #ea6153 !important;\n}\n\n.btn-warning {\n  background-color: #E67E22 !important;\n}\n.btn-warning:hover {\n  background-color: #e98b39 !important;\n}\n\n.btn-invert {\n  background-color: #222;\n}\n.btn-invert:hover {\n  background-color: #2f2f2f !important;\n}\n\n.btn-link {\n  background-color: transparent !important;\n  color: #0E6FD2;\n  box-shadow: none;\n  border-color: transparent !important;\n}\n.btn-link:hover {\n  background-color: transparent !important;\n  color: #2388f0 !important;\n  box-shadow: none;\n}\n.btn-link:active {\n  background-color: transparent !important;\n  color: #2388f0 !important;\n  box-shadow: none;\n}\n.btn-link:visited {\n  color: #9B59B6;\n}\n\n.wy-btn-group .btn, .wy-control .btn {\n  vertical-align: middle;\n}\n\n.wy-btn-group {\n  margin-bottom: 24px;\n  *zoom: 1;\n}\n.wy-btn-group:before, .wy-btn-group:after {\n  display: table;\n  content: \"\";\n}\n.wy-btn-group:after {\n  clear: both;\n}\n\n.wy-dropdown {\n  position: relative;\n  display: inline-block;\n}\n\n.wy-dropdown-active .wy-dropdown-menu {\n  display: block;\n}\n\n.wy-dropdown-menu {\n  position: absolute;\n  left: 0;\n  display: none;\n  float: left;\n  top: 100%;\n  min-width: 100%;\n  background: #fcfcfc;\n  z-index: 100;\n  border: solid 1px #cfd7dd;\n  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1);\n  padding: 12px;\n}\n.wy-dropdown-menu > dd > a {\n  display: block;\n  clear: both;\n  color: #404040;\n  white-space: nowrap;\n  font-size: 90%;\n  padding: 0 12px;\n  cursor: pointer;\n}\n.wy-dropdown-menu > dd > a:hover {\n  background: #0E6FD2;\n  color: #fff;\n}\n.wy-dropdown-menu > dd.divider {\n  border-top: solid 1px #cfd7dd;\n  margin: 6px 0;\n}\n.wy-dropdown-menu > dd.search {\n  padding-bottom: 12px;\n}\n.wy-dropdown-menu > dd.search input[type=\"search\"] {\n  width: 100%;\n}\n.wy-dropdown-menu > dd.call-to-action {\n  background: #e3e3e3;\n  text-transform: uppercase;\n  font-weight: 500;\n  font-size: 80%;\n}\n.wy-dropdown-menu > dd.call-to-action:hover {\n  background: #e3e3e3;\n}\n.wy-dropdown-menu > dd.call-to-action .btn {\n  color: #fff;\n}\n\n.wy-dropdown.wy-dropdown-up .wy-dropdown-menu {\n  bottom: 100%;\n  top: auto;\n  left: auto;\n  right: 0;\n}\n\n.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu {\n  background: #fcfcfc;\n  margin-top: 2px;\n}\n.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a {\n  padding: 6px 12px;\n}\n.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover {\n  background: #0E6FD2;\n  color: #fff;\n}\n\n.wy-dropdown.wy-dropdown-left .wy-dropdown-menu {\n  right: 0;\n  left: auto;\n  text-align: right;\n}\n\n.wy-dropdown-arrow:before {\n  content: \" \";\n  border-bottom: 5px solid whitesmoke;\n  border-left: 5px solid transparent;\n  border-right: 5px solid transparent;\n  position: absolute;\n  display: block;\n  top: -4px;\n  left: 50%;\n  margin-left: -3px;\n}\n.wy-dropdown-arrow.wy-dropdown-arrow-left:before {\n  left: 11px;\n}\n\n.wy-form-stacked select {\n  display: block;\n}\n\n.wy-form-aligned input, .wy-form-aligned textarea, .wy-form-aligned select, .wy-form-aligned .wy-help-inline, .wy-form-aligned label {\n  display: inline-block;\n  *display: inline;\n  *zoom: 1;\n  vertical-align: middle;\n}\n\n.wy-form-aligned .wy-control-group > label {\n  display: inline-block;\n  vertical-align: middle;\n  width: 10em;\n  margin: 6px 12px 0 0;\n  float: left;\n}\n.wy-form-aligned .wy-control {\n  float: left;\n}\n.wy-form-aligned .wy-control label {\n  display: block;\n}\n.wy-form-aligned .wy-control select {\n  margin-top: 6px;\n}\n\nfieldset {\n  border: 0;\n  margin: 0;\n  padding: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  border: 0;\n  padding: 0;\n  white-space: normal;\n  margin-bottom: 24px;\n  font-size: 150%;\n  *margin-left: -7px;\n}\n\nlabel {\n  display: block;\n  margin: 0 0 0.3125em 0;\n  color: #333;\n  font-size: 90%;\n}\n\ninput, select, textarea {\n  font-size: 100%;\n  margin: 0;\n  vertical-align: baseline;\n  *vertical-align: middle;\n}\n\n.wy-control-group {\n  margin-bottom: 24px;\n  *zoom: 1;\n  max-width: 68em;\n  margin-left: auto;\n  margin-right: auto;\n  *zoom: 1;\n}\n.wy-control-group:before, .wy-control-group:after {\n  display: table;\n  content: \"\";\n}\n.wy-control-group:after {\n  clear: both;\n}\n.wy-control-group:before, .wy-control-group:after {\n  display: table;\n  content: \"\";\n}\n.wy-control-group:after {\n  clear: both;\n}\n\n.wy-control-group.wy-control-group-required > label:after {\n  content: \" *\";\n  color: #E74C3C;\n}\n\n.wy-control-group .wy-form-full, .wy-control-group .wy-form-halves, .wy-control-group .wy-form-thirds {\n  padding-bottom: 12px;\n}\n.wy-control-group .wy-form-full select, .wy-control-group .wy-form-halves select, .wy-control-group .wy-form-thirds select {\n  width: 100%;\n}\n.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\"] {\n  width: 100%;\n}\n\n.wy-control-group .wy-form-full {\n  float: left;\n  display: block;\n  margin-right: 2.35765%;\n  width: 100%;\n  margin-right: 0;\n}\n.wy-control-group .wy-form-full:last-child {\n  margin-right: 0;\n}\n\n.wy-control-group .wy-form-halves {\n  float: left;\n  display: block;\n  margin-right: 2.35765%;\n  width: 48.82117%;\n}\n.wy-control-group .wy-form-halves:last-child {\n  margin-right: 0;\n}\n.wy-control-group .wy-form-halves:nth-of-type(2n) {\n  margin-right: 0;\n}\n.wy-control-group .wy-form-halves:nth-of-type(2n+1) {\n  clear: left;\n}\n\n.wy-control-group .wy-form-thirds {\n  float: left;\n  display: block;\n  margin-right: 2.35765%;\n  width: 31.76157%;\n}\n.wy-control-group .wy-form-thirds:last-child {\n  margin-right: 0;\n}\n.wy-control-group .wy-form-thirds:nth-of-type(3n) {\n  margin-right: 0;\n}\n.wy-control-group .wy-form-thirds:nth-of-type(3n+1) {\n  clear: left;\n}\n\n.wy-control-group.wy-control-group-no-input .wy-control {\n  margin: 6px 0 0 0;\n  font-size: 90%;\n}\n\n.wy-control-no-input {\n  display: inline-block;\n  margin: 6px 0 0 0;\n  font-size: 90%;\n}\n\n.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\"] {\n  width: 100%;\n}\n\n.wy-form-message-inline {\n  display: inline-block;\n  padding-left: 0.3em;\n  color: #666;\n  vertical-align: middle;\n  font-size: 90%;\n}\n\n.wy-form-message {\n  display: block;\n  color: #999;\n  font-size: 70%;\n  margin-top: 0.3125em;\n  font-style: italic;\n}\n.wy-form-message p {\n  font-size: inherit;\n  font-style: italic;\n  margin-bottom: 6px;\n}\n.wy-form-message p:last-child {\n  margin-bottom: 0;\n}\n\ninput {\n  line-height: normal;\n}\n\ninput[type=\"button\"], input[type=\"reset\"], input[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  *overflow: visible;\n}\ninput[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\"] {\n  -webkit-appearance: none;\n  padding: 6px;\n  display: inline-block;\n  border: 1px solid #ccc;\n  font-size: 80%;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  box-shadow: inset 0 1px 3px #ddd;\n  border-radius: 0;\n  -webkit-transition: border 0.3s linear;\n  -moz-transition: border 0.3s linear;\n  transition: border 0.3s linear;\n}\ninput[type=\"datetime-local\"] {\n  padding: 0.34375em 0.625em;\n}\ninput[disabled] {\n  cursor: default;\n}\ninput[type=\"checkbox\"], input[type=\"radio\"] {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  padding: 0;\n  margin-right: 0.3125em;\n  *height: 13px;\n  *width: 13px;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button, input[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\ninput[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 {\n  outline: 0;\n  outline: thin dotted \\9;\n  border-color: #333;\n}\ninput.no-focus:focus {\n  border-color: #ccc !important;\n}\ninput[type=\"file\"]:focus, input[type=\"radio\"]:focus, input[type=\"checkbox\"]:focus {\n  outline: thin dotted #333;\n  outline: 1px auto #129FEA;\n}\ninput[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] {\n  cursor: not-allowed;\n  background-color: #fafafa;\n}\n\ninput:focus:invalid, textarea:focus:invalid, select:focus:invalid {\n  color: #E74C3C;\n  border: 1px solid #E74C3C;\n}\n\ninput:focus:invalid:focus, textarea:focus:invalid:focus, select:focus:invalid:focus {\n  border-color: #E74C3C;\n}\n\ninput[type=\"file\"]:focus:invalid:focus, input[type=\"radio\"]:focus:invalid:focus, input[type=\"checkbox\"]:focus:invalid:focus {\n  outline-color: #E74C3C;\n}\n\ninput.wy-input-large {\n  padding: 12px;\n  font-size: 100%;\n}\n\ntextarea {\n  overflow: auto;\n  vertical-align: top;\n  width: 100%;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n}\n\nselect, textarea {\n  padding: 0.5em 0.625em;\n  display: inline-block;\n  border: 1px solid #ccc;\n  font-size: 80%;\n  box-shadow: inset 0 1px 3px #ddd;\n  -webkit-transition: border 0.3s linear;\n  -moz-transition: border 0.3s linear;\n  transition: border 0.3s linear;\n}\n\nselect {\n  border: 1px solid #ccc;\n  background-color: #fff;\n}\nselect[multiple] {\n  height: auto;\n}\n\nselect:focus, textarea:focus {\n  outline: 0;\n}\n\nselect[disabled], textarea[disabled], input[readonly], select[readonly], textarea[readonly] {\n  cursor: not-allowed;\n  background-color: #fafafa;\n}\n\ninput[type=\"radio\"][disabled], input[type=\"checkbox\"][disabled] {\n  cursor: not-allowed;\n}\n\n.wy-checkbox, .wy-radio {\n  margin: 6px 0;\n  color: #404040;\n  display: block;\n}\n.wy-checkbox input, .wy-radio input {\n  vertical-align: baseline;\n}\n\n.wy-form-message-inline {\n  display: inline-block;\n  *display: inline;\n  *zoom: 1;\n  vertical-align: middle;\n}\n\n.wy-input-prefix, .wy-input-suffix {\n  white-space: nowrap;\n  padding: 6px;\n}\n.wy-input-prefix .wy-input-context, .wy-input-suffix .wy-input-context {\n  line-height: 27px;\n  padding: 0 8px;\n  display: inline-block;\n  font-size: 80%;\n  background-color: #f3f6f6;\n  border: solid 1px #ccc;\n  color: #999;\n}\n\n.wy-input-suffix .wy-input-context {\n  border-left: 0;\n}\n\n.wy-input-prefix .wy-input-context {\n  border-right: 0;\n}\n\n.wy-switch {\n  width: 36px;\n  height: 12px;\n  margin: 12px 0;\n  position: relative;\n  border-radius: 4px;\n  background: #ccc;\n  cursor: pointer;\n  -webkit-transition: all 0.2s ease-in-out;\n  -moz-transition: all 0.2s ease-in-out;\n  transition: all 0.2s ease-in-out;\n}\n.wy-switch:before {\n  position: absolute;\n  content: \"\";\n  display: block;\n  width: 18px;\n  height: 18px;\n  border-radius: 4px;\n  background: #999;\n  left: -3px;\n  top: -3px;\n  -webkit-transition: all 0.2s ease-in-out;\n  -moz-transition: all 0.2s ease-in-out;\n  transition: all 0.2s ease-in-out;\n}\n.wy-switch:after {\n  content: \"false\";\n  position: absolute;\n  left: 48px;\n  display: block;\n  font-size: 12px;\n  color: #ccc;\n}\n\n.wy-switch.active {\n  background: #1e8449;\n}\n.wy-switch.active:before {\n  left: 24px;\n  background: #27AE60;\n}\n.wy-switch.active:after {\n  content: \"true\";\n}\n\n.wy-switch.disabled, .wy-switch.active.disabled {\n  cursor: not-allowed;\n}\n\n.wy-control-group.wy-control-group-error .wy-form-message, .wy-control-group.wy-control-group-error > label {\n  color: #E74C3C;\n}\n.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\"] {\n  border: solid 1px #E74C3C;\n}\n.wy-control-group.wy-control-group-error textarea {\n  border: solid 1px #E74C3C;\n}\n\n.wy-inline-validate {\n  white-space: nowrap;\n}\n.wy-inline-validate .wy-input-context {\n  padding: 0.5em 0.625em;\n  display: inline-block;\n  font-size: 80%;\n}\n\n.wy-inline-validate.wy-inline-validate-success .wy-input-context {\n  color: #27AE60;\n}\n\n.wy-inline-validate.wy-inline-validate-danger .wy-input-context {\n  color: #E74C3C;\n}\n\n.wy-inline-validate.wy-inline-validate-warning .wy-input-context {\n  color: #E67E22;\n}\n\n.wy-inline-validate.wy-inline-validate-info .wy-input-context {\n  color: #0E6FD2;\n}\n\n.rotate-90 {\n  -webkit-transform: rotate(90deg);\n  -moz-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  -o-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n\n.rotate-180 {\n  -webkit-transform: rotate(180deg);\n  -moz-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  -o-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n\n.rotate-270 {\n  -webkit-transform: rotate(270deg);\n  -moz-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  -o-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n\n.mirror {\n  -webkit-transform: scaleX(-1);\n  -moz-transform: scaleX(-1);\n  -ms-transform: scaleX(-1);\n  -o-transform: scaleX(-1);\n  transform: scaleX(-1);\n}\n.mirror.rotate-90 {\n  -webkit-transform: scaleX(-1) rotate(90deg);\n  -moz-transform: scaleX(-1) rotate(90deg);\n  -ms-transform: scaleX(-1) rotate(90deg);\n  -o-transform: scaleX(-1) rotate(90deg);\n  transform: scaleX(-1) rotate(90deg);\n}\n.mirror.rotate-180 {\n  -webkit-transform: scaleX(-1) rotate(180deg);\n  -moz-transform: scaleX(-1) rotate(180deg);\n  -ms-transform: scaleX(-1) rotate(180deg);\n  -o-transform: scaleX(-1) rotate(180deg);\n  transform: scaleX(-1) rotate(180deg);\n}\n.mirror.rotate-270 {\n  -webkit-transform: scaleX(-1) rotate(270deg);\n  -moz-transform: scaleX(-1) rotate(270deg);\n  -ms-transform: scaleX(-1) rotate(270deg);\n  -o-transform: scaleX(-1) rotate(270deg);\n  transform: scaleX(-1) rotate(270deg);\n}\n\n@media only screen and (max-width: 480px) {\n  .wy-form button[type=\"submit\"] {\n    margin: 0.7em 0 0;\n  }\n  .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\"] {\n    margin-bottom: 0.3em;\n    display: block;\n  }\n  .wy-form label {\n    margin-bottom: 0.3em;\n    display: block;\n  }\n\n  .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\"] {\n    margin-bottom: 0;\n  }\n\n  .wy-form-aligned .wy-control-group label {\n    margin-bottom: 0.3em;\n    text-align: left;\n    display: block;\n    width: 100%;\n  }\n  .wy-form-aligned .wy-control {\n    margin: 1.5em 0 0 0;\n  }\n\n  .wy-form .wy-help-inline, .wy-form-message-inline, .wy-form-message {\n    display: block;\n    font-size: 80%;\n    padding: 6px 0;\n  }\n}\n@media screen and (max-width: 768px) {\n  .tablet-hide {\n    display: none;\n  }\n}\n\n@media screen and (max-width: 480px) {\n  .mobile-hide {\n    display: none;\n  }\n}\n\n.float-left {\n  float: left;\n}\n\n.float-right {\n  float: right;\n}\n\n.full-width {\n  width: 100%;\n}\n\n.wy-table, .rst-content table.docutils, .rst-content table.field-list {\n  border-collapse: collapse;\n  border-spacing: 0;\n  empty-cells: show;\n  margin-bottom: 24px;\n}\n.wy-table caption, .rst-content table.docutils caption, .rst-content table.field-list caption {\n  color: #000;\n  font: italic 85%/1 arial, sans-serif;\n  padding: 1em 0;\n  text-align: center;\n}\n.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 {\n  font-size: 90%;\n  margin: 0;\n  overflow: visible;\n  padding: 8px 16px;\n}\n.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 {\n  border-left-width: 0;\n}\n.wy-table thead, .rst-content table.docutils thead, .rst-content table.field-list thead {\n  color: #000;\n  text-align: left;\n  vertical-align: bottom;\n  white-space: nowrap;\n}\n.wy-table thead th, .rst-content table.docutils thead th, .rst-content table.field-list thead th {\n  font-weight: bold;\n  border-bottom: solid 2px #e1e4e5;\n}\n.wy-table td, .rst-content table.docutils td, .rst-content table.field-list td {\n  background-color: transparent;\n  vertical-align: middle;\n}\n\n.wy-table td p, .rst-content table.docutils td p, .rst-content table.field-list td p {\n  line-height: 18px;\n}\n.wy-table td p:last-child, .rst-content table.docutils td p:last-child, .rst-content table.field-list td p:last-child {\n  margin-bottom: 0;\n}\n\n.wy-table .wy-table-cell-min, .rst-content table.docutils .wy-table-cell-min, .rst-content table.field-list .wy-table-cell-min {\n  width: 1%;\n  padding-right: 0;\n}\n.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] {\n  margin: 0;\n}\n\n.wy-table-secondary {\n  color: gray;\n  font-size: 90%;\n}\n\n.wy-table-tertiary {\n  color: gray;\n  font-size: 80%;\n}\n\n.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 {\n  background-color: #f3f6f6;\n}\n\n.wy-table-backed {\n  background-color: #f3f6f6;\n}\n\n/* BORDERED TABLES */\n.wy-table-bordered-all, .rst-content table.docutils {\n  border: 1px solid #e1e4e5;\n}\n.wy-table-bordered-all td, .rst-content table.docutils td {\n  border-bottom: 1px solid #e1e4e5;\n  border-left: 1px solid #e1e4e5;\n}\n.wy-table-bordered-all tbody > tr:last-child td, .rst-content table.docutils tbody > tr:last-child td {\n  border-bottom-width: 0;\n}\n\n.wy-table-bordered {\n  border: 1px solid #e1e4e5;\n}\n\n.wy-table-bordered-rows td {\n  border-bottom: 1px solid #e1e4e5;\n}\n.wy-table-bordered-rows tbody > tr:last-child td {\n  border-bottom-width: 0;\n}\n\n.wy-table-horizontal tbody > tr:last-child td {\n  border-bottom-width: 0;\n}\n.wy-table-horizontal td, .wy-table-horizontal th {\n  border-width: 0 0 1px 0;\n  border-bottom: 1px solid #e1e4e5;\n}\n.wy-table-horizontal tbody > tr:last-child td {\n  border-bottom-width: 0;\n}\n\n/* RESPONSIVE TABLES */\n.wy-table-responsive {\n  margin-bottom: 24px;\n  max-width: 100%;\n  overflow: auto;\n}\n.wy-table-responsive table {\n  margin-bottom: 0 !important;\n}\n.wy-table-responsive table td, .wy-table-responsive table th {\n  white-space: nowrap;\n}\n\na {\n  color: #0E6FD2;\n  text-decoration: none;\n  cursor: pointer;\n}\na:hover {\n  color: #107eef;\n}\na:visited {\n  color: #9B59B6;\n}\n\nhtml {\n  height: 100%;\n  overflow-x: hidden;\n}\n\nbody {\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  font-weight: normal;\n  color: #404040;\n  min-height: 100%;\n  overflow-x: hidden;\n  background: #edf0f2;\n}\n\n.wy-text-left {\n  text-align: left;\n}\n\n.wy-text-center {\n  text-align: center;\n}\n\n.wy-text-right {\n  text-align: right;\n}\n\n.wy-text-large {\n  font-size: 120%;\n}\n\n.wy-text-normal {\n  font-size: 100%;\n}\n\n.wy-text-small, small {\n  font-size: 80%;\n}\n\n.wy-text-strike {\n  text-decoration: line-through;\n}\n\n.wy-text-warning {\n  color: #E67E22 !important;\n}\n\na.wy-text-warning:hover {\n  color: #eb9950 !important;\n}\n\n.wy-text-info {\n  color: #0E6FD2 !important;\n}\n\na.wy-text-info:hover {\n  color: #2388f0 !important;\n}\n\n.wy-text-success {\n  color: #27AE60 !important;\n}\n\na.wy-text-success:hover {\n  color: #36d278 !important;\n}\n\n.wy-text-danger {\n  color: #E74C3C !important;\n}\n\na.wy-text-danger:hover {\n  color: #ed7669 !important;\n}\n\n.wy-text-neutral {\n  color: #404040 !important;\n}\n\na.wy-text-neutral:hover {\n  color: #595959 !important;\n}\n\nh1, h2, .rst-content .toctree-wrapper p.caption, h3, h4, h5, h6, legend {\n  margin-top: 0;\n  font-weight: 700;\n  font-family: \"Roboto Slab\", \"ff-tisa-web-pro\", \"Georgia\", Arial, sans-serif;\n}\n\np {\n  line-height: 24px;\n  margin: 0;\n  font-size: 16px;\n  margin-bottom: 24px;\n}\n\nh1 {\n  font-size: 175%;\n}\n\nh2, .rst-content .toctree-wrapper p.caption {\n  font-size: 150%;\n}\n\nh3 {\n  font-size: 125%;\n}\n\nh4 {\n  font-size: 115%;\n}\n\nh5 {\n  font-size: 110%;\n}\n\nh6 {\n  font-size: 100%;\n}\n\nhr {\n  display: block;\n  height: 1px;\n  border: 0;\n  border-top: 1px solid #e1e4e5;\n  margin: 24px 0;\n  padding: 0;\n}\n\ncode, .rst-content tt, .rst-content code {\n  white-space: nowrap;\n  max-width: 100%;\n  background: #fff;\n  border: solid 1px #e1e4e5;\n  font-size: 75%;\n  padding: 0 5px;\n  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;\n  color: #E74C3C;\n  overflow-x: auto;\n}\ncode.code-large, .rst-content tt.code-large {\n  font-size: 90%;\n}\n\n.wy-plain-list-disc, .rst-content .section ul, .rst-content .toctree-wrapper ul, article ul {\n  list-style: disc;\n  line-height: 24px;\n  margin-bottom: 24px;\n}\n.wy-plain-list-disc li, .rst-content .section ul li, .rst-content .toctree-wrapper ul li, article ul li {\n  list-style: disc;\n  margin-left: 24px;\n}\n.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 {\n  margin-bottom: 0;\n}\n.wy-plain-list-disc li ul, .rst-content .section ul li ul, .rst-content .toctree-wrapper ul li ul, article ul li ul {\n  margin-bottom: 0;\n}\n.wy-plain-list-disc li li, .rst-content .section ul li li, .rst-content .toctree-wrapper ul li li, article ul li li {\n  list-style: circle;\n}\n.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 {\n  list-style: square;\n}\n.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 {\n  list-style: decimal;\n}\n\n.wy-plain-list-decimal, .rst-content .section ol, .rst-content ol.arabic, article ol {\n  list-style: decimal;\n  line-height: 24px;\n  margin-bottom: 24px;\n}\n.wy-plain-list-decimal li, .rst-content .section ol li, .rst-content ol.arabic li, article ol li {\n  list-style: decimal;\n  margin-left: 24px;\n}\n.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 {\n  margin-bottom: 0;\n}\n.wy-plain-list-decimal li ul, .rst-content .section ol li ul, .rst-content ol.arabic li ul, article ol li ul {\n  margin-bottom: 0;\n}\n.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 {\n  list-style: disc;\n}\n\n.codeblock-example {\n  border: 1px solid #e1e4e5;\n  border-bottom: none;\n  padding: 24px;\n  padding-top: 48px;\n  font-weight: 500;\n  background: #fff;\n  position: relative;\n}\n.codeblock-example:after {\n  content: \"Example\";\n  position: absolute;\n  top: 0px;\n  left: 0px;\n  background: #9B59B6;\n  color: white;\n  padding: 6px 12px;\n}\n.codeblock-example.prettyprint-example-only {\n  border: 1px solid #e1e4e5;\n  margin-bottom: 24px;\n}\n\n.codeblock, pre.literal-block, .rst-content .literal-block, .rst-content pre.literal-block, div[class^='highlight'] {\n  border: 1px solid #e1e4e5;\n  padding: 0px;\n  overflow-x: auto;\n  background: #fff;\n  margin: 1px 0 24px 0;\n}\n.codeblock div[class^='highlight'], pre.literal-block div[class^='highlight'], .rst-content .literal-block div[class^='highlight'], div[class^='highlight'] div[class^='highlight'] {\n  border: none;\n  background: none;\n  margin: 0;\n}\n\ndiv[class^='highlight'] td.code {\n  width: 100%;\n}\n\n.linenodiv pre {\n  border-right: solid 1px #e6e9ea;\n  margin: 0;\n  padding: 12px 12px;\n  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;\n  font-size: 12px;\n  line-height: 1.5;\n  color: #d9d9d9;\n}\n\ndiv[class^='highlight'] pre {\n  white-space: pre;\n  margin: 0;\n  padding: 12px 12px;\n  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;\n  font-size: 12px;\n  line-height: 1.5;\n  display: block;\n  overflow: auto;\n  color: #404040;\n}\n\n@media print {\n  .codeblock, pre.literal-block, .rst-content .literal-block, .rst-content pre.literal-block, div[class^='highlight'], div[class^='highlight'] pre {\n    white-space: pre-wrap;\n  }\n}\n.hll {\n  background-color: #ffffcc;\n  margin: 0 -12px;\n  padding: 0 12px;\n  display: block;\n}\n\n.c {\n  color: #999988;\n  font-style: italic;\n}\n\n.err {\n  color: #a61717;\n  background-color: #e3d2d2;\n}\n\n.k {\n  font-weight: bold;\n}\n\n.o {\n  font-weight: bold;\n}\n\n.cm {\n  color: #999988;\n  font-style: italic;\n}\n\n.cp {\n  color: #999999;\n  font-weight: bold;\n}\n\n.c1 {\n  color: #999988;\n  font-style: italic;\n}\n\n.cs {\n  color: #999999;\n  font-weight: bold;\n  font-style: italic;\n}\n\n.gd {\n  color: #000000;\n  background-color: #ffdddd;\n}\n\n.gd .x {\n  color: #000000;\n  background-color: #ffaaaa;\n}\n\n.ge {\n  font-style: italic;\n}\n\n.gr {\n  color: #aa0000;\n}\n\n.gh {\n  color: #999999;\n}\n\n.gi {\n  color: #000000;\n  background-color: #ddffdd;\n}\n\n.gi .x {\n  color: #000000;\n  background-color: #aaffaa;\n}\n\n.go {\n  color: #888888;\n}\n\n.gp {\n  color: #555555;\n}\n\n.gs {\n  font-weight: bold;\n}\n\n.gu {\n  color: #800080;\n  font-weight: bold;\n}\n\n.gt {\n  color: #aa0000;\n}\n\n.kc {\n  font-weight: bold;\n}\n\n.kd {\n  font-weight: bold;\n}\n\n.kn {\n  font-weight: bold;\n}\n\n.kp {\n  font-weight: bold;\n}\n\n.kr {\n  font-weight: bold;\n}\n\n.kt {\n  color: #445588;\n  font-weight: bold;\n}\n\n.m {\n  color: #009999;\n}\n\n.s {\n  color: #dd1144;\n}\n\n.n {\n  color: #333333;\n}\n\n.na {\n  color: teal;\n}\n\n.nb {\n  color: #0086b3;\n}\n\n.nc {\n  color: #445588;\n  font-weight: bold;\n}\n\n.no {\n  color: teal;\n}\n\n.ni {\n  color: purple;\n}\n\n.ne {\n  color: #990000;\n  font-weight: bold;\n}\n\n.nf {\n  color: #990000;\n  font-weight: bold;\n}\n\n.nn {\n  color: #555555;\n}\n\n.nt {\n  color: navy;\n}\n\n.nv {\n  color: teal;\n}\n\n.ow {\n  font-weight: bold;\n}\n\n.w {\n  color: #bbbbbb;\n}\n\n.mf {\n  color: #009999;\n}\n\n.mh {\n  color: #009999;\n}\n\n.mi {\n  color: #009999;\n}\n\n.mo {\n  color: #009999;\n}\n\n.sb {\n  color: #dd1144;\n}\n\n.sc {\n  color: #dd1144;\n}\n\n.sd {\n  color: #dd1144;\n}\n\n.s2 {\n  color: #dd1144;\n}\n\n.se {\n  color: #dd1144;\n}\n\n.sh {\n  color: #dd1144;\n}\n\n.si {\n  color: #dd1144;\n}\n\n.sx {\n  color: #dd1144;\n}\n\n.sr {\n  color: #009926;\n}\n\n.s1 {\n  color: #dd1144;\n}\n\n.ss {\n  color: #990073;\n}\n\n.bp {\n  color: #999999;\n}\n\n.vc {\n  color: teal;\n}\n\n.vg {\n  color: teal;\n}\n\n.vi {\n  color: teal;\n}\n\n.il {\n  color: #009999;\n}\n\n.gc {\n  color: #999;\n  background-color: #EAF2F5;\n}\n\n.wy-breadcrumbs li {\n  display: inline-block;\n}\n.wy-breadcrumbs li.wy-breadcrumbs-aside {\n  float: right;\n}\n.wy-breadcrumbs li a {\n  display: inline-block;\n  padding: 5px;\n}\n.wy-breadcrumbs li a:first-child {\n  padding-left: 0;\n}\n.wy-breadcrumbs li code, .wy-breadcrumbs li .rst-content tt, .rst-content .wy-breadcrumbs li tt {\n  padding: 5px;\n  border: none;\n  background: none;\n}\n.wy-breadcrumbs li code.literal, .wy-breadcrumbs li .rst-content tt.literal, .rst-content .wy-breadcrumbs li tt.literal {\n  color: #404040;\n}\n\n.wy-breadcrumbs-extra {\n  margin-bottom: 0;\n  color: #b3b3b3;\n  font-size: 80%;\n  display: inline-block;\n}\n\n@media screen and (max-width: 480px) {\n  .wy-breadcrumbs-extra {\n    display: none;\n  }\n\n  .wy-breadcrumbs li.wy-breadcrumbs-aside {\n    display: none;\n  }\n}\n@media print {\n  .wy-breadcrumbs li.wy-breadcrumbs-aside {\n    display: none;\n  }\n}\nem {\n  font-style: normal;\n}\n\na:visited {\n  color: #0E6FD2;\n}\n\n.simple {\n  margin-bottom: 0 !important;\n}\n\na.btn.btn-neutral {\n  padding: 5px 14px;\n  background-color: #ffffff !important;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  margin-top: 15px;\n  box-shadow: none;\n  color: #0E6FD2 !important;\n}\n\na.btn.btn-neutral:hover {\n  background-color: #eee !important;\n}\n\n.wy-side-scroll .wy-side-nav-search input[type=text] {\n  border-radius: 0 !important;\n  border: 1px solid #00b7ee;\n}\n\n.wy-affixs {\n  position: fixed;\n  top: 1.618em;\n}\n\n.wy-menu a:hover {\n  text-decoration: none;\n}\n\n.wy-menu-horiz {\n  *zoom: 1;\n}\n.wy-menu-horiz:before, .wy-menu-horiz:after {\n  display: table;\n  content: \"\";\n}\n.wy-menu-horiz:after {\n  clear: both;\n}\n.wy-menu-horiz ul, .wy-menu-horiz li {\n  display: inline-block;\n}\n.wy-menu-horiz li:hover {\n  background: rgba(255, 255, 255, 0.1);\n}\n.wy-menu-horiz li.divide-left {\n  border-left: solid 1px #404040;\n}\n.wy-menu-horiz li.divide-right {\n  border-right: solid 1px #404040;\n}\n.wy-menu-horiz a {\n  height: 32px;\n  display: inline-block;\n  line-height: 32px;\n  padding: 0 16px;\n}\n\n.wy-menu-vertical {\n  width: 300px;\n}\n.wy-menu-vertical header, .wy-menu-vertical p.caption {\n  height: 32px;\n  display: inline-block;\n  line-height: 32px;\n  padding: 0 1.618em;\n  margin-bottom: 0;\n  display: block;\n  font-weight: bold;\n  text-transform: uppercase;\n  font-size: 80%;\n  color: #555;\n  white-space: nowrap;\n}\n.wy-menu-vertical ul {\n  margin-bottom: 0;\n}\n.wy-menu-vertical li.divide-top {\n  border-top: solid 1px #404040;\n}\n.wy-menu-vertical li.divide-bottom {\n  border-bottom: solid 1px #404040;\n}\n.wy-menu-vertical li.current {\n  background: #e3e3e3;\n}\n.wy-menu-vertical li.current a {\n  color: gray;\n  border-right: solid 1px #c9c9c9;\n  padding: 0.4045em 2.427em;\n}\n.wy-menu-vertical li.current a:hover {\n  background: #d6d6d6;\n}\n.wy-menu-vertical li code, .wy-menu-vertical li .rst-content tt, .rst-content .wy-menu-vertical li tt {\n  border: none;\n  background: inherit;\n  color: inherit;\n  padding-left: 0;\n  padding-right: 0;\n}\n.wy-menu-vertical li span.toctree-expand {\n  display: block;\n  float: left;\n  margin-left: -1.2em;\n  font-size: 0.8em;\n  line-height: 1.6em;\n  color: #4d4d4d;\n}\n.wy-menu-vertical li.on a, .wy-menu-vertical li.current > a {\n  color: #0E6FD2;\n  padding: 0.4045em 1.618em;\n  font-weight: bold;\n  position: relative;\n  background: #343131 !important;\n  border: none;\n  padding-left: 1.618em -4px;\n}\n.wy-menu-vertical li.on a:hover, .wy-menu-vertical li.current > a:hover {\n  background: #fcfcfc;\n}\n.wy-menu-vertical li.on a:hover span.toctree-expand, .wy-menu-vertical li.current > a:hover span.toctree-expand {\n  color: gray;\n}\n.wy-menu-vertical li.on a span.toctree-expand, .wy-menu-vertical li.current > a span.toctree-expand {\n  display: block;\n  font-size: 0.8em;\n  line-height: 1.6em;\n  color: #333333;\n}\n.wy-menu-vertical li.toctree-l1.current, .wy-menu-vertical li.toctree-l1.current li.toctree-l2, .wy-menu-vertical li.toctree-l2.current li {\n  color: #0E6FD2;\n  background: #343131;\n}\n.wy-menu-vertical li.toctree-l1.current span.toctree-expand, .wy-menu-vertical li.toctree-l1.current li.toctree-l2 span.toctree-expand, .wy-menu-vertical li.toctree-l2.current li span.toctree-expand {\n  color: #343131;\n}\n.wy-menu-vertical li.toctree-l1.current > a:hover, .wy-menu-vertical li.toctree-l1.current li.toctree-l2 > a:hover, .wy-menu-vertical li.toctree-l2.current li > a:hover {\n  color: #0E6FD2;\n  background: #343131;\n  border-bottom: 0;\n  border-top: 0;\n}\n.wy-menu-vertical li.toctree-l1.current > a:hover span.toctree-expand, .wy-menu-vertical li.toctree-l1.current li.toctree-l2 > a:hover span.toctree-expand, .wy-menu-vertical li.toctree-l2.current li > a:hover span.toctree-expand {\n  color: #0E6FD2;\n}\n.wy-menu-vertical li.toctree-l1.current > ul, .wy-menu-vertical li.toctree-l1.current li.toctree-l2 > ul, .wy-menu-vertical li.toctree-l2.current li > ul {\n  display: none;\n}\n.wy-menu-vertical li.toctree-l1.current.current > ul, .wy-menu-vertical li.toctree-l1.current li.toctree-l2.current > ul, .wy-menu-vertical li.toctree-l2.current li.current > ul {\n  display: block;\n}\n.wy-menu-vertical li.toctree-l2 a {\n  border-right: 0;\n}\n.wy-menu-vertical li.toctree-l2.current {\n  background: #343131;\n}\n.wy-menu-vertical li.toctree-l2.current > a {\n  background: #343131;\n  padding: 0.4045em 2.427em;\n}\n.wy-menu-vertical li.toctree-l2.current > a span.toctree-expand {\n  color: #343131;\n}\n.wy-menu-vertical li.toctree-l2.current li.toctree-l3 > a {\n  display: block;\n  background: #343131;\n  padding: 0.4045em 4.045em;\n}\n.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand {\n  color: gray;\n  background: #343131;\n}\n.wy-menu-vertical li.toctree-l2 span.toctree-expand {\n  color: #a3a3a3;\n}\n.wy-menu-vertical li.toctree-l3 {\n  font-size: 0.9em;\n}\n.wy-menu-vertical li.toctree-l3 a {\n  border-right: 0;\n}\n.wy-menu-vertical li.toctree-l3.current > a {\n  background: #343131;\n  padding: 0.4045em 4.045em;\n}\n.wy-menu-vertical li.toctree-l3.current li.toctree-l4 > a {\n  display: block;\n  background: #343131;\n  padding: 0.4045em 5.663em;\n  border-top: none;\n  border-bottom: none;\n}\n.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand {\n  color: #0E6FD2;\n}\n.wy-menu-vertical li.toctree-l3 span.toctree-expand {\n  color: #969696;\n}\n.wy-menu-vertical li.toctree-l4 {\n  font-size: 0.9em;\n}\n.wy-menu-vertical li.current ul {\n  display: block;\n}\n.wy-menu-vertical li ul {\n  margin-bottom: 0;\n  display: none;\n}\n.wy-menu-vertical .local-toc li ul {\n  display: block;\n}\n.wy-menu-vertical li ul li a {\n  margin-bottom: 0;\n  color: #b3b3b3;\n  font-weight: normal;\n}\n.wy-menu-vertical a {\n  display: inline-block;\n  line-height: 18px;\n  padding: 0.4045em 1.618em;\n  display: block;\n  position: relative;\n  font-size: 90%;\n  color: #b3b3b3;\n}\n.wy-menu-vertical a:hover {\n  background-color: #4e4a4a;\n  cursor: pointer;\n}\n.wy-menu-vertical a:hover span.toctree-expand {\n  color: #b3b3b3;\n}\n.wy-menu-vertical a:active {\n  background-color: #0E6FD2;\n  cursor: pointer;\n  color: #fff;\n}\n.wy-menu-vertical a:active span.toctree-expand {\n  color: #fff;\n}\n\n.wy-side-nav-search {\n  display: block;\n  width: 300px;\n  padding: 0.809em;\n  margin-bottom: 0.809em;\n  z-index: 200;\n  background-image: linear-gradient(#0E7EE4 0%, #343131 100%);\n  background-color: #0E6FD2;\n  text-align: center;\n  color: #fcfcfc;\n}\n.wy-side-nav-search input[type=text] {\n  width: 100%;\n  border-radius: 50px;\n  padding: 6px 12px;\n  border-color: #0c62ba;\n}\n.wy-side-nav-search img {\n  display: block;\n  margin: auto auto 0.809em auto;\n  height: 45px;\n  width: 45px;\n  background-color: #0E6FD2;\n  padding: 5px;\n  border-radius: 100%;\n}\n.wy-side-nav-search > a, .wy-side-nav-search .wy-dropdown > a {\n  color: #fcfcfc;\n  font-size: 100%;\n  font-weight: bold;\n  display: inline-block;\n  padding: 4px 6px;\n  margin-bottom: 0.809em;\n}\n.wy-side-nav-search > a:hover, .wy-side-nav-search .wy-dropdown > a:hover {\n  background: rgba(255, 255, 255, 0.1);\n}\n.wy-side-nav-search > a img.logo, .wy-side-nav-search .wy-dropdown > a img.logo {\n  display: block;\n  margin: 0 auto;\n  height: auto;\n  width: auto;\n  border-radius: 0;\n  max-width: 100%;\n  background: transparent;\n}\n.wy-side-nav-search > a.icon img.logo, .wy-side-nav-search .wy-dropdown > a.icon img.logo {\n  margin-top: 0.85em;\n}\n.wy-side-nav-search > div.version {\n  margin-top: -0.4045em;\n  margin-bottom: 0.809em;\n  font-weight: normal;\n  color: rgba(255, 255, 255, 0.3);\n}\n\n.wy-nav .wy-menu-vertical header {\n  color: #0E6FD2;\n}\n.wy-nav .wy-menu-vertical a {\n  color: #b3b3b3;\n}\n.wy-nav .wy-menu-vertical a:hover {\n  background-color: #0E6FD2;\n  color: #fff;\n}\n\n[data-menu-wrap] {\n  -webkit-transition: all 0.2s ease-in;\n  -moz-transition: all 0.2s ease-in;\n  transition: all 0.2s ease-in;\n  position: absolute;\n  opacity: 1;\n  width: 100%;\n  opacity: 0;\n}\n[data-menu-wrap].move-center {\n  left: 0;\n  right: auto;\n  opacity: 1;\n}\n[data-menu-wrap].move-left {\n  right: auto;\n  left: -100%;\n  opacity: 0;\n}\n[data-menu-wrap].move-right {\n  right: -100%;\n  left: auto;\n  opacity: 0;\n}\n\n.wy-body-for-nav {\n  background: left repeat-y #fcfcfc;\n  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);\n  background-size: 300px 1px;\n  color: #444;\n}\n\n.wy-grid-for-nav {\n  position: absolute;\n  width: 100%;\n  height: 100%;\n}\n\n.wy-nav-side {\n  position: fixed;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  padding-bottom: 2em;\n  width: 300px;\n  overflow-x: hidden;\n  overflow-y: hidden;\n  min-height: 100%;\n  background: #343131;\n  z-index: 200;\n}\n\n.wy-side-scroll {\n  width: 320px;\n  position: relative;\n  overflow-x: hidden;\n  overflow-y: scroll;\n  height: 100%;\n}\n\n.wy-nav-top {\n  display: none;\n  background: #0E6FD2;\n  color: #fff;\n  padding: 0.4045em 0.809em;\n  position: relative;\n  line-height: 50px;\n  text-align: center;\n  font-size: 100%;\n  *zoom: 1;\n}\n.wy-nav-top:before, .wy-nav-top:after {\n  display: table;\n  content: \"\";\n}\n.wy-nav-top:after {\n  clear: both;\n}\n.wy-nav-top a {\n  color: #fff;\n  font-weight: bold;\n}\n.wy-nav-top img {\n  margin-right: 12px;\n  height: 45px;\n  width: 45px;\n  background-color: #0E6FD2;\n  padding: 5px;\n  border-radius: 100%;\n}\n.wy-nav-top i {\n  font-size: 30px;\n  float: left;\n  cursor: pointer;\n  padding-top: inherit;\n}\n\n.wy-nav-content-wrap {\n  margin-left: 300px;\n  background: #fcfcfc;\n  min-height: 100%;\n}\n\n.wy-nav-content {\n  padding: 1.618em 3.236em;\n  height: 100%;\n  min-height: 100vh;\n  margin: auto;\n}\n\n.wy-body-mask {\n  position: fixed;\n  width: 100%;\n  height: 100%;\n  background: rgba(0, 0, 0, 0.2);\n  display: none;\n  z-index: 499;\n}\n.wy-body-mask.on {\n  display: block;\n}\n\nfooter {\n  color: #999;\n}\nfooter p {\n  margin-bottom: 12px;\n}\nfooter span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt {\n  padding: 0px;\n  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;\n  font-size: 1em;\n  background: none;\n  border: none;\n  color: #999;\n}\n\n.rst-footer-buttons {\n  *zoom: 1;\n}\n.rst-footer-buttons:before, .rst-footer-buttons:after {\n  display: table;\n  content: \"\";\n}\n.rst-footer-buttons:after {\n  clear: both;\n}\n\n.document {\n  min-height: 58vh;\n}\n\n#search-results .search li {\n  margin-bottom: 24px;\n  border-bottom: solid 1px #e1e4e5;\n  padding-bottom: 24px;\n}\n#search-results .search li:first-child {\n  border-top: solid 1px #e1e4e5;\n  padding-top: 24px;\n}\n#search-results .search li a {\n  font-size: 120%;\n  margin-bottom: 12px;\n  display: inline-block;\n}\n#search-results .context {\n  color: gray;\n  font-size: 90%;\n}\n\n@media screen and (max-width: 768px) {\n  .wy-body-for-nav {\n    background: #fcfcfc;\n  }\n\n  .wy-nav-top {\n    display: block;\n  }\n\n  .wy-nav-side {\n    left: -300px;\n  }\n  .wy-nav-side.shift {\n    width: 85%;\n    left: 0;\n  }\n\n  .wy-side-scroll {\n    width: auto;\n  }\n\n  .wy-side-nav-search {\n    width: auto;\n  }\n\n  .wy-menu.wy-menu-vertical {\n    width: auto;\n  }\n\n  .wy-nav-content-wrap {\n    margin-left: 0;\n  }\n  .wy-nav-content-wrap .wy-nav-content {\n    padding: 1.618em;\n  }\n  .wy-nav-content-wrap.shift {\n    position: fixed;\n    min-width: 100%;\n    left: 85%;\n    top: 0;\n    height: 100%;\n    overflow: hidden;\n  }\n}\n@media screen and (min-width: 1400px) {\n  .wy-nav-content-wrap {\n    background: rgba(0, 0, 0, 0.05);\n  }\n\n  .wy-nav-content {\n    margin: 0;\n    background: #fcfcfc;\n  }\n\n  .document {\n    min-height: 71vh;\n  }\n}\n@media print {\n  .rst-versions, footer, .wy-nav-side {\n    display: none;\n  }\n\n  .wy-nav-content-wrap {\n    margin-left: 0;\n  }\n}\n.rst-versions {\n  position: fixed;\n  bottom: 0;\n  left: 0;\n  width: 300px;\n  color: #fcfcfc;\n  background: #1f1d1d;\n  border-top: solid 10px #343131;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  z-index: 400;\n}\n.rst-versions a {\n  color: #0E6FD2;\n  text-decoration: none;\n}\n.rst-versions .rst-badge-small {\n  display: none;\n}\n.rst-versions .rst-current-version {\n  padding: 12px;\n  background-color: #272525;\n  display: block;\n  text-align: right;\n  font-size: 90%;\n  cursor: pointer;\n  color: #27AE60;\n  *zoom: 1;\n}\n.rst-versions .rst-current-version:before, .rst-versions .rst-current-version:after {\n  display: table;\n  content: \"\";\n}\n.rst-versions .rst-current-version:after {\n  clear: both;\n}\n.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 {\n  color: #fcfcfc;\n}\n.rst-versions .rst-current-version .fa-book, .rst-versions .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions .rst-current-version.rst-out-of-date {\n  background-color: #E74C3C;\n  color: #fff;\n}\n.rst-versions .rst-current-version.rst-active-old-version {\n  background-color: #F1C40F;\n  color: #000;\n}\n.rst-versions.shift-up .rst-other-versions {\n  display: block;\n}\n.rst-versions .rst-other-versions {\n  font-size: 90%;\n  padding: 12px;\n  color: gray;\n  display: none;\n}\n.rst-versions .rst-other-versions hr {\n  display: block;\n  height: 1px;\n  border: 0;\n  margin: 20px 0;\n  padding: 0;\n  border-top: solid 1px #413d3d;\n}\n.rst-versions .rst-other-versions dd {\n  display: inline-block;\n  margin: 0;\n}\n.rst-versions .rst-other-versions dd a {\n  display: inline-block;\n  padding: 6px;\n  color: #fcfcfc;\n}\n.rst-versions.rst-badge {\n  width: auto;\n  bottom: 20px;\n  right: 20px;\n  left: auto;\n  border: none;\n  max-width: 300px;\n}\n.rst-versions.rst-badge .icon-book {\n  float: none;\n}\n.rst-versions.rst-badge .fa-book, .rst-versions.rst-badge .icon-book {\n  float: none;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version {\n  text-align: right;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version .fa-book, .rst-versions.rst-badge.shift-up .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions.rst-badge .rst-current-version {\n  width: auto;\n  height: 30px;\n  line-height: 30px;\n  padding: 0 6px;\n  display: block;\n  text-align: center;\n}\n\n@media screen and (max-width: 768px) {\n  .rst-versions {\n    width: 85%;\n    display: none;\n  }\n  .rst-versions.shift {\n    display: block;\n  }\n\n  img {\n    width: 100%;\n    height: auto;\n  }\n}\n.rst-content img {\n  max-width: 100%;\n  height: auto !important;\n}\n.rst-content div.figure {\n  margin-bottom: 24px;\n}\n.rst-content div.figure p.caption {\n  font-style: italic;\n}\n.rst-content div.figure.align-center {\n  text-align: center;\n}\n.rst-content .section > img, .rst-content .section > a > img {\n  margin-bottom: 24px;\n}\n.rst-content blockquote {\n  margin-left: 24px;\n  line-height: 24px;\n  margin-bottom: 24px;\n}\n.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 {\n  margin-bottom: 0;\n}\n.rst-content .admonition-title:before {\n  margin-right: 4px;\n}\n.rst-content .admonition table {\n  border-color: rgba(0, 0, 0, 0.1);\n}\n.rst-content .admonition table td, .rst-content .admonition table th {\n  background: transparent !important;\n  border-color: rgba(0, 0, 0, 0.1) !important;\n}\n.rst-content .toctree-wrapper ul li {\n  list-style: none;\n  margin-left: 20px;\n}\n.rst-content .section ol.loweralpha, .rst-content .section ol.loweralpha li {\n  list-style: lower-alpha;\n}\n.rst-content .section ol.upperalpha, .rst-content .section ol.upperalpha li {\n  list-style: upper-alpha;\n}\n.rst-content .section ol p, .rst-content .section ul p {\n  margin-bottom: 12px;\n}\n.rst-content .line-block {\n  margin-left: 24px;\n}\n.rst-content .topic .topic-title {\n  font-size: 16px;\n  line-height: 20px;\n  color: #555;\n  font-weight: bold;\n  margin: 12px 0;\n}\n.rst-content .topic {\n  margin: 0 30px;\n}\n.rst-content .toc-backref {\n  color: #404040;\n}\n.rst-content .align-right {\n  float: right;\n  margin: 0 0 24px 24px;\n}\n.rst-content .align-left {\n  float: left;\n  margin: 0 24px 24px 0;\n}\n.rst-content .align-center {\n  margin: auto;\n  display: block;\n}\n.rst-content .document h1 {\n  font-size: 23px;\n  line-height: 40px;\n}\n.rst-content .document h2, .rst-content .document .toctree-wrapper p.caption, .rst-content .toctree-wrapper .document p.caption {\n  font-size: 21px;\n  line-height: 30px;\n  font-weight: 400;\n  margin-top: 20px;\n}\n.rst-content .document h3 {\n  font-size: 18px;\n  line-height: 20px;\n  font-weight: 400;\n  margin-top: 15px;\n}\n.rst-content .document p {\n  font-size: 14px;\n  margin: 0 0 1px 0;\n}\n.rst-content .document a.reference.external, .rst-content .document a.reference.external em, .rst-content .document a.reference.internal, .rst-content .document a.reference.internal em {\n  color: #0E6FD2;\n  text-decoration: none;\n  cursor: pointer;\n  font-style: normal;\n}\n.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 {\n  display: none;\n  visibility: hidden;\n  font-size: 14px;\n}\n.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 {\n  visibility: visible;\n  content: \"\";\n  font-family: FontAwesome;\n  display: inline-block;\n}\n.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 {\n  display: inline-block;\n}\n.rst-content .sidebar {\n  float: right;\n  width: 40%;\n  display: block;\n  margin: 0 0 24px 24px;\n  padding: 24px;\n  background: #f3f6f6;\n  border: solid 1px #e1e4e5;\n}\n.rst-content .sidebar p, .rst-content .sidebar ul, .rst-content .sidebar dl {\n  font-size: 90%;\n}\n.rst-content .sidebar .last {\n  margin-bottom: 0;\n}\n.rst-content .sidebar .sidebar-title {\n  display: block;\n  font-family: \"Roboto Slab\", \"ff-tisa-web-pro\", \"Georgia\", Arial, sans-serif;\n  font-weight: bold;\n  background: #e1e4e5;\n  padding: 6px 12px;\n  margin: -24px;\n  margin-bottom: 24px;\n  font-size: 100%;\n}\n.rst-content .highlighted {\n  background: #F1C40F;\n  display: inline-block;\n  font-weight: bold;\n  padding: 0 6px;\n}\n.rst-content .footnote-reference, .rst-content .citation-reference {\n  vertical-align: super;\n  font-size: 90%;\n}\n.rst-content table.docutils.citation, .rst-content table.docutils.footnote {\n  background: none;\n  border: none;\n  color: #999;\n}\n.rst-content table.docutils.citation td, .rst-content table.docutils.citation tr, .rst-content table.docutils.footnote td, .rst-content table.docutils.footnote tr {\n  border: none;\n  background-color: transparent !important;\n  white-space: normal;\n}\n.rst-content table.docutils.citation td.label, .rst-content table.docutils.footnote td.label {\n  padding-left: 0;\n  padding-right: 0;\n  vertical-align: top;\n}\n.rst-content table.docutils.citation tt, .rst-content table.docutils.citation code, .rst-content table.docutils.footnote tt, .rst-content table.docutils.footnote code {\n  color: #555;\n}\n.rst-content table.field-list {\n  border: none;\n}\n.rst-content table.field-list td {\n  border: none;\n  padding-top: 5px;\n}\n.rst-content table.field-list td > strong {\n  display: inline-block;\n  margin-top: 3px;\n}\n.rst-content table.field-list .field-name {\n  padding-right: 10px;\n  text-align: left;\n  white-space: nowrap;\n}\n.rst-content table.field-list .field-body {\n  text-align: left;\n  padding-left: 0;\n}\n.rst-content tt, .rst-content tt, .rst-content code {\n  color: #000;\n  padding: 2px 5px;\n}\n.rst-content tt big, .rst-content tt em, .rst-content tt big, .rst-content code big, .rst-content tt em, .rst-content code em {\n  font-size: 100% !important;\n  line-height: normal;\n}\n.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal {\n  color: #888;\n  background-color: rgba(0, 0, 0, 0.04);\n  border: none;\n  font-size: 13px;\n}\n.rst-content tt.xref, a .rst-content tt, .rst-content tt.xref, .rst-content code.xref, a .rst-content tt, a .rst-content code {\n  font-weight: bold;\n  color: #404040;\n}\n.rst-content a tt, .rst-content a tt, .rst-content a code {\n  color: #0E6FD2;\n}\n.rst-content dl {\n  margin-bottom: 24px;\n}\n.rst-content dl dt {\n  font-weight: bold;\n}\n.rst-content dl p, .rst-content dl table, .rst-content dl ul, .rst-content dl ol {\n  margin-bottom: 12px !important;\n}\n.rst-content dl dd {\n  margin: 0 0 12px 24px;\n}\n.rst-content dl:not(.docutils) {\n  margin-bottom: 24px;\n}\n.rst-content dl:not(.docutils) dt {\n  display: inline-block;\n  margin: 6px 0;\n  font-size: 90%;\n  line-height: normal;\n  background: #e2effd;\n  color: #0E6FD2;\n  border-top: solid 3px #53a2f4;\n  padding: 6px;\n  position: relative;\n}\n.rst-content dl:not(.docutils) dt:before {\n  color: #53a2f4;\n}\n.rst-content dl:not(.docutils) dt .headerlink {\n  color: #404040;\n  font-size: 100% !important;\n}\n.rst-content dl:not(.docutils) dl dt {\n  margin-bottom: 6px;\n  border: none;\n  border-left: solid 3px #cccccc;\n  background: #f0f0f0;\n  color: #555;\n}\n.rst-content dl:not(.docutils) dl dt .headerlink {\n  color: #404040;\n  font-size: 100% !important;\n}\n.rst-content dl:not(.docutils) dt:first-child {\n  margin-top: 0;\n}\n.rst-content dl:not(.docutils) tt, .rst-content dl:not(.docutils) tt, .rst-content dl:not(.docutils) code {\n  font-weight: bold;\n}\n.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 {\n  background-color: transparent;\n  border: none;\n  padding: 0;\n  font-size: 100% !important;\n}\n.rst-content dl:not(.docutils) tt.descname, .rst-content dl:not(.docutils) tt.descname, .rst-content dl:not(.docutils) code.descname {\n  font-weight: bold;\n}\n.rst-content dl:not(.docutils) .optional {\n  display: inline-block;\n  padding: 0 4px;\n  color: #000;\n  font-weight: bold;\n}\n.rst-content dl:not(.docutils) .property {\n  display: inline-block;\n  padding-right: 8px;\n}\n.rst-content .viewcode-link, .rst-content .viewcode-back {\n  display: inline-block;\n  color: #27AE60;\n  font-size: 80%;\n  padding-left: 24px;\n}\n.rst-content .viewcode-back {\n  display: block;\n  float: right;\n}\n.rst-content p.rubric {\n  margin-bottom: 12px;\n  font-weight: bold;\n}\n.rst-content tt.download, .rst-content code.download {\n  background: inherit;\n  padding: inherit;\n  font-family: inherit;\n  font-size: inherit;\n  color: inherit;\n  border: inherit;\n  white-space: inherit;\n}\n.rst-content tt.download span:first-child:before, .rst-content code.download span:first-child:before {\n  margin-right: 4px;\n}\n\n@media screen and (max-width: 480px) {\n  .rst-content .sidebar {\n    width: 100%;\n  }\n}\nspan[id*='MathJax-Span'] {\n  color: #404040;\n}\n\n.math {\n  text-align: center;\n}\n\n@font-face {\n  font-family: \"Inconsolata\";\n  font-style: normal;\n  font-weight: 400;\n  src: local(\"Inconsolata\"), local(\"Inconsolata-Regular\"), url(../fonts/Inconsolata-Regular.ttf) format(\"truetype\");\n}\n@font-face {\n  font-family: \"Inconsolata\";\n  font-style: normal;\n  font-weight: 700;\n  src: local(\"Inconsolata Bold\"), local(\"Inconsolata-Bold\"), url(../fonts/Inconsolata-Bold.ttf) format(\"truetype\");\n}\n@font-face {\n  font-family: \"Lato\";\n  font-style: normal;\n  font-weight: 400;\n  src: local(\"Lato Regular\"), local(\"Lato-Regular\"), url(../fonts/Lato-Regular.ttf) format(\"truetype\");\n}\n@font-face {\n  font-family: \"Lato\";\n  font-style: normal;\n  font-weight: 700;\n  src: local(\"Lato Bold\"), local(\"Lato-Bold\"), url(../fonts/Lato-Bold.ttf) format(\"truetype\");\n}\n@font-face {\n  font-family: \"Roboto Slab\";\n  font-style: normal;\n  font-weight: 400;\n  src: local(\"Roboto Slab Regular\"), local(\"RobotoSlab-Regular\"), url(../fonts/RobotoSlab-Regular.ttf) format(\"truetype\");\n}\n@font-face {\n  font-family: \"Roboto Slab\";\n  font-style: normal;\n  font-weight: 700;\n  src: local(\"Roboto Slab Bold\"), local(\"RobotoSlab-Bold\"), url(../fonts/RobotoSlab-Bold.ttf) format(\"truetype\");\n}\n\n/*# sourceMappingURL=theme.css.map */\n"
  },
  {
    "path": "docs/_static/custom.css",
    "content": "/* This file intentionally left blank. */\n"
  },
  {
    "path": "docs/_static/doctools.js",
    "content": "/*\n * doctools.js\n * ~~~~~~~~~~~\n *\n * Sphinx JavaScript utilities for all documentation.\n *\n * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n/**\n * select a different prefix for underscore\n */\n$u = _.noConflict();\n\n/**\n * make the code below compatible with browsers without\n * an installed firebug like debugger\nif (!window.console || !console.firebug) {\n  var names = [\"log\", \"debug\", \"info\", \"warn\", \"error\", \"assert\", \"dir\",\n    \"dirxml\", \"group\", \"groupEnd\", \"time\", \"timeEnd\", \"count\", \"trace\",\n    \"profile\", \"profileEnd\"];\n  window.console = {};\n  for (var i = 0; i < names.length; ++i)\n    window.console[names[i]] = function() {};\n}\n */\n\n/**\n * small helper function to urldecode strings\n */\njQuery.urldecode = function(x) {\n  return decodeURIComponent(x).replace(/\\+/g, ' ');\n};\n\n/**\n * small helper function to urlencode strings\n */\njQuery.urlencode = encodeURIComponent;\n\n/**\n * This function returns the parsed url parameters of the\n * current request. Multiple values per key are supported,\n * it will always return arrays of strings for the value parts.\n */\njQuery.getQueryParameters = function(s) {\n  if (typeof s == 'undefined')\n    s = document.location.search;\n  var parts = s.substr(s.indexOf('?') + 1).split('&');\n  var result = {};\n  for (var i = 0; i < parts.length; i++) {\n    var tmp = parts[i].split('=', 2);\n    var key = jQuery.urldecode(tmp[0]);\n    var value = jQuery.urldecode(tmp[1]);\n    if (key in result)\n      result[key].push(value);\n    else\n      result[key] = [value];\n  }\n  return result;\n};\n\n/**\n * highlight a given string on a jquery object by wrapping it in\n * span elements with the given class name.\n */\njQuery.fn.highlightText = function(text, className) {\n  function highlight(node) {\n    if (node.nodeType == 3) {\n      var val = node.nodeValue;\n      var pos = val.toLowerCase().indexOf(text);\n      if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {\n        var span = document.createElement(\"span\");\n        span.className = className;\n        span.appendChild(document.createTextNode(val.substr(pos, text.length)));\n        node.parentNode.insertBefore(span, node.parentNode.insertBefore(\n          document.createTextNode(val.substr(pos + text.length)),\n          node.nextSibling));\n        node.nodeValue = val.substr(0, pos);\n      }\n    }\n    else if (!jQuery(node).is(\"button, select, textarea\")) {\n      jQuery.each(node.childNodes, function() {\n        highlight(this);\n      });\n    }\n  }\n  return this.each(function() {\n    highlight(this);\n  });\n};\n\n/*\n * backward compatibility for jQuery.browser\n * This will be supported until firefox bug is fixed.\n */\nif (!jQuery.browser) {\n  jQuery.uaMatch = function(ua) {\n    ua = ua.toLowerCase();\n\n    var match = /(chrome)[ \\/]([\\w.]+)/.exec(ua) ||\n      /(webkit)[ \\/]([\\w.]+)/.exec(ua) ||\n      /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec(ua) ||\n      /(msie) ([\\w.]+)/.exec(ua) ||\n      ua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec(ua) ||\n      [];\n\n    return {\n      browser: match[ 1 ] || \"\",\n      version: match[ 2 ] || \"0\"\n    };\n  };\n  jQuery.browser = {};\n  jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;\n}\n\n/**\n * Small JavaScript module for the documentation.\n */\nvar Documentation = {\n\n  init : function() {\n    this.fixFirefoxAnchorBug();\n    this.highlightSearchWords();\n    this.initIndexTable();\n    \n  },\n\n  /**\n   * i18n support\n   */\n  TRANSLATIONS : {},\n  PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },\n  LOCALE : 'unknown',\n\n  // gettext and ngettext don't access this so that the functions\n  // can safely bound to a different name (_ = Documentation.gettext)\n  gettext : function(string) {\n    var translated = Documentation.TRANSLATIONS[string];\n    if (typeof translated == 'undefined')\n      return string;\n    return (typeof translated == 'string') ? translated : translated[0];\n  },\n\n  ngettext : function(singular, plural, n) {\n    var translated = Documentation.TRANSLATIONS[singular];\n    if (typeof translated == 'undefined')\n      return (n == 1) ? singular : plural;\n    return translated[Documentation.PLURALEXPR(n)];\n  },\n\n  addTranslations : function(catalog) {\n    for (var key in catalog.messages)\n      this.TRANSLATIONS[key] = catalog.messages[key];\n    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');\n    this.LOCALE = catalog.locale;\n  },\n\n  /**\n   * add context elements like header anchor links\n   */\n  addContextElements : function() {\n    $('div[id] > :header:first').each(function() {\n      $('<a class=\"headerlink\">\\u00B6</a>').\n      attr('href', '#' + this.id).\n      attr('title', _('Permalink to this headline')).\n      appendTo(this);\n    });\n    $('dt[id]').each(function() {\n      $('<a class=\"headerlink\">\\u00B6</a>').\n      attr('href', '#' + this.id).\n      attr('title', _('Permalink to this definition')).\n      appendTo(this);\n    });\n  },\n\n  /**\n   * workaround a firefox stupidity\n   * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075\n   */\n  fixFirefoxAnchorBug : function() {\n    if (document.location.hash)\n      window.setTimeout(function() {\n        document.location.href += '';\n      }, 10);\n  },\n\n  /**\n   * highlight the search words provided in the url in the text\n   */\n  highlightSearchWords : function() {\n    var params = $.getQueryParameters();\n    var terms = (params.highlight) ? params.highlight[0].split(/\\s+/) : [];\n    if (terms.length) {\n      var body = $('div.body');\n      if (!body.length) {\n        body = $('body');\n      }\n      window.setTimeout(function() {\n        $.each(terms, function() {\n          body.highlightText(this.toLowerCase(), 'highlighted');\n        });\n      }, 10);\n      $('<p class=\"highlight-link\"><a href=\"javascript:Documentation.' +\n        'hideSearchWords()\">' + _('Hide Search Matches') + '</a></p>')\n          .appendTo($('#searchbox'));\n    }\n  },\n\n  /**\n   * init the domain index toggle buttons\n   */\n  initIndexTable : function() {\n    var togglers = $('img.toggler').click(function() {\n      var src = $(this).attr('src');\n      var idnum = $(this).attr('id').substr(7);\n      $('tr.cg-' + idnum).toggle();\n      if (src.substr(-9) == 'minus.png')\n        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');\n      else\n        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');\n    }).css('display', '');\n    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {\n        togglers.click();\n    }\n  },\n\n  /**\n   * helper function to hide the search marks again\n   */\n  hideSearchWords : function() {\n    $('#searchbox .highlight-link').fadeOut(300);\n    $('span.highlighted').removeClass('highlighted');\n  },\n\n  /**\n   * make the url absolute\n   */\n  makeURL : function(relativeURL) {\n    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;\n  },\n\n  /**\n   * get the current relative url\n   */\n  getCurrentURL : function() {\n    var path = document.location.pathname;\n    var parts = path.split(/\\//);\n    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\\//), function() {\n      if (this == '..')\n        parts.pop();\n    });\n    var url = parts.join('/');\n    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);\n  },\n\n  initOnKeyListeners: function() {\n    $(document).keyup(function(event) {\n      var activeElementType = document.activeElement.tagName;\n      // don't navigate when in search box or textarea\n      if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') {\n        switch (event.keyCode) {\n          case 37: // left\n            var prevHref = $('link[rel=\"prev\"]').prop('href');\n            if (prevHref) {\n              window.location.href = prevHref;\n              return false;\n            }\n          case 39: // right\n            var nextHref = $('link[rel=\"next\"]').prop('href');\n            if (nextHref) {\n              window.location.href = nextHref;\n              return false;\n            }\n        }\n      }\n    });\n  }\n};\n\n// quick alias for translations\n_ = Documentation.gettext;\n\n$(document).ready(function() {\n  Documentation.init();\n});"
  },
  {
    "path": "docs/_static/documentation_options.js",
    "content": "var DOCUMENTATION_OPTIONS = {\n    URL_ROOT: document.getElementById(\"documentation_options\").getAttribute('data-url_root'),\n    VERSION: '',\n    LANGUAGE: 'en',\n    COLLAPSE_INDEX: false,\n    BUILDER: 'html',\n    FILE_SUFFIX: '.html',\n    LINK_SUFFIX: '.html',\n    HAS_SOURCE: true,\n    SOURCELINK_SUFFIX: '.txt',\n    NAVIGATION_WITH_KEYS: false,\n    SHOW_SEARCH_SUMMARY: true,\n    ENABLE_SEARCH_SHORTCUTS: true,\n};"
  },
  {
    "path": "docs/_static/epub.css",
    "content": "/*\n * default.css_t\n * ~~~~~~~~~~~~~\n *\n * Sphinx stylesheet -- default theme.\n *\n * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n@import url(\"basic.css\");\n\n/* -- page layout ----------------------------------------------------------- */\n\nbody {\n    font-family: {{ theme_bodyfont }};\n    font-size: 100%;\n    background-color: {{ theme_footerbgcolor }};\n    color: #000;\n    margin: 0;\n    padding: 0;\n}\n\ndiv.document {\n    background-color: {{ theme_sidebarbgcolor }};\n}\n\ndiv.documentwrapper {\n    float: left;\n    width: 100%;\n}\n\ndiv.bodywrapper {\n    margin: 0 0 0 230px;\n}\n\ndiv.body {\n    background-color: {{ theme_bgcolor }};\n    color: {{ theme_textcolor }};\n    padding: 0 20px 30px 20px;\n}\n\n{%- if theme_rightsidebar|tobool %}\ndiv.bodywrapper {\n    margin: 0 230px 0 0;\n}\n{%- endif %}\n\ndiv.footer {\n    color: {{ theme_footertextcolor }};\n    width: 100%;\n    padding: 9px 0 9px 0;\n    text-align: center;\n    font-size: 75%;\n}\n\ndiv.footer a {\n    color: {{ theme_footertextcolor }};\n    text-decoration: underline;\n}\n\ndiv.related {\n    background-color: {{ theme_relbarbgcolor }};\n    line-height: 30px;\n    color: {{ theme_relbartextcolor }};\n}\n\ndiv.related a {\n    color: {{ theme_relbarlinkcolor }};\n}\n\ndiv.sphinxsidebar {\n    {%- if theme_stickysidebar|tobool %}\n    top: 30px;\n    bottom: 0;\n    margin: 0;\n    position: fixed;\n    overflow: auto;\n    height: auto;\n    {%- endif %}\n    {%- if theme_rightsidebar|tobool %}\n    float: right;\n    {%- if theme_stickysidebar|tobool %}\n    right: 0;\n    {%- endif %}\n    {%- endif %}\n}\n\n{%- if theme_stickysidebar|tobool %}\n/* this is nice, but it it leads to hidden headings when jumping\n   to an anchor */\n/*\ndiv.related {\n    position: fixed;\n}\n\ndiv.documentwrapper {\n    margin-top: 30px;\n}\n*/\n{%- endif %}\n\ndiv.sphinxsidebar h3 {\n    font-family: {{ theme_headfont }};\n    color: {{ theme_sidebartextcolor }};\n    font-size: 1.4em;\n    font-weight: normal;\n    margin: 0;\n    padding: 0;\n}\n\ndiv.sphinxsidebar h3 a {\n    color: {{ theme_sidebartextcolor }};\n}\n\ndiv.sphinxsidebar h4 {\n    font-family: {{ theme_headfont }};\n    color: {{ theme_sidebartextcolor }};\n    font-size: 1.3em;\n    font-weight: normal;\n    margin: 5px 0 0 0;\n    padding: 0;\n}\n\ndiv.sphinxsidebar p {\n    color: {{ theme_sidebartextcolor }};\n}\n\ndiv.sphinxsidebar p.topless {\n    margin: 5px 10px 10px 10px;\n}\n\ndiv.sphinxsidebar ul {\n    margin: 10px;\n    padding: 0;\n    color: {{ theme_sidebartextcolor }};\n}\n\ndiv.sphinxsidebar a {\n    color: {{ theme_sidebarlinkcolor }};\n}\n\ndiv.sphinxsidebar input {\n    border: 1px solid {{ theme_sidebarlinkcolor }};\n    font-family: sans-serif;\n    font-size: 1em;\n}\n\n{% if theme_collapsiblesidebar|tobool %}\n/* for collapsible sidebar */\ndiv#sidebarbutton {\n    background-color: {{ theme_sidebarbtncolor }};\n}\n{% endif %}\n\n/* -- hyperlink styles ------------------------------------------------------ */\n\na {\n    color: {{ theme_linkcolor }};\n    text-decoration: none;\n}\n\na:visited {\n    color: {{ theme_visitedlinkcolor }};\n    text-decoration: none;\n}\n\na:hover {\n    text-decoration: underline;\n}\n\n{% if theme_externalrefs|tobool %}\na.external {\n   text-decoration: none;\n   border-bottom: 1px dashed {{ theme_linkcolor }};\n}\n\na.external:hover {\n   text-decoration: none;\n   border-bottom: none;\n}\n\na.external:visited {\n    text-decoration: none;\n    border-bottom: 1px dashed {{ theme_visitedlinkcolor }};\n}\n{% endif %}\n\n/* -- body styles ----------------------------------------------------------- */\n\ndiv.body h1,\ndiv.body h2,\ndiv.body h3,\ndiv.body h4,\ndiv.body h5,\ndiv.body h6 {\n    font-family: {{ theme_headfont }};\n    background-color: {{ theme_headbgcolor }};\n    font-weight: normal;\n    color: {{ theme_headtextcolor }};\n    border-bottom: 1px solid #ccc;\n    margin: 20px -20px 10px -20px;\n    padding: 3px 0 3px 10px;\n}\n\ndiv.body h1 { margin-top: 0; font-size: 200%; }\ndiv.body h2 { font-size: 160%; }\ndiv.body h3 { font-size: 140%; }\ndiv.body h4 { font-size: 120%; }\ndiv.body h5 { font-size: 110%; }\ndiv.body h6 { font-size: 100%; }\n\na.headerlink {\n    color: {{ theme_headlinkcolor }};\n    font-size: 0.8em;\n    padding: 0 4px 0 4px;\n    text-decoration: none;\n}\n\na.headerlink:hover {\n    background-color: {{ theme_headlinkcolor }};\n    color: white;\n}\n\ndiv.body p, div.body dd, div.body li {\n    text-align: justify;\n    line-height: 130%;\n}\n\ndiv.admonition p.admonition-title + p {\n    display: inline;\n}\n\ndiv.admonition p {\n    margin-bottom: 5px;\n}\n\ndiv.admonition pre {\n    margin-bottom: 5px;\n}\n\ndiv.admonition ul, div.admonition ol {\n    margin-bottom: 5px;\n}\n\ndiv.note {\n    background-color: #eee;\n    border: 1px solid #ccc;\n}\n\ndiv.seealso {\n    background-color: #ffc;\n    border: 1px solid #ff6;\n}\n\ndiv.topic {\n    background-color: #eee;\n}\n\ndiv.warning {\n    background-color: #ffe4e4;\n    border: 1px solid #f66;\n}\n\np.admonition-title {\n    display: inline;\n}\n\np.admonition-title:after {\n    content: \":\";\n}\n\npre {\n    padding: 5px;\n    background-color: {{ theme_codebgcolor }};\n    color: {{ theme_codetextcolor }};\n    line-height: 120%;\n    border: 1px solid #ac9;\n    border-left: none;\n    border-right: none;\n}\n\ncode {\n    background-color: #ecf0f3;\n    padding: 0 1px 0 1px;\n    font-size: 0.95em;\n}\n\nth {\n    background-color: #ede;\n}\n\n.warning code {\n    background: #efc2c2;\n}\n\n.note code {\n    background: #d6d6d6;\n}\n\n.viewcode-back {\n    font-family: {{ theme_bodyfont }};\n}\n\ndiv.viewcode-block:target {\n    background-color: #f4debf;\n    border-top: 1px solid #ac9;\n    border-bottom: 1px solid #ac9;\n}\n"
  },
  {
    "path": "docs/_static/ie6.css",
    "content": "* html img,\n* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior=\"none\")&&(this.pngSet?this.pngSet=true:(this.nodeName == \"IMG\" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = \"none\",\nthis.runtimeStyle.filter = \"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='\" + this.src + \"',sizingMethod='image')\",\nthis.src = \"_static/transparent.gif\"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url(\"','').replace('\")',''),\nthis.runtimeStyle.filter = \"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='\" + this.origBg + \"',sizingMethod='crop')\",\nthis.runtimeStyle.backgroundImage = \"none\")),this.pngSet=true)\n);}\n"
  },
  {
    "path": "docs/_static/jquery-3.1.0.js",
    "content": "/*eslint-disable no-unused-vars*/\n/*!\n * jQuery JavaScript Library v3.1.0\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2016-07-07T21:44Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar document = window.document;\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\n\n\n\tfunction DOMEval( code, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar script = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n/* global Symbol */\n// Defining this global in .eslintrc would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.1.0\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android <=4.0 only\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = jQuery.isArray( copy ) ) ) ) {\n\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray( src ) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject( src ) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type( obj ) === \"function\";\n\t},\n\n\tisArray: Array.isArray,\n\n\tisWindow: function( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\n\t\t// As of jQuery 3.0, isNumeric is limited to\n\t\t// strings and numbers (primitives or objects)\n\t\t// that can be coerced to finite numbers (gh-2662)\n\t\tvar type = jQuery.type( obj );\n\t\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t\t// subtraction forces infinities to NaN\n\t\t\t!isNaN( obj - parseFloat( obj ) );\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\n\t\t/* eslint-disable no-unused-vars */\n\t\t// See https://github.com/eslint/eslint/issues/6125\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\n\t\t// Support: Android <=2.3 only (functionish RegExp)\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code ) {\n\t\tDOMEval( code );\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Support: IE <=9 - 11, Edge 12 - 13\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android <=4.0 only\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar tmp, args, proxy;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: Date.now,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.0\n * https://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2016-01-04\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\x80-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tdisabledAncestor = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\n\t\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\t\tsetDocument( context );\n\t\t}\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( (m = match[1]) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( (elem = context.getElementById( m )) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && (elem = newContext.getElementById( m )) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[2] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!compilerCache[ selector + \" \" ] &&\n\t\t\t\t(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\n\t\t\t\tif ( nodeType !== 1 ) {\n\t\t\t\t\tnewContext = context;\n\t\t\t\t\tnewSelector = selector;\n\n\t\t\t\t// qSA looks outside Element context, which is not what we want\n\t\t\t\t// Thanks to Andrew Dupont for this workaround technique\n\t\t\t\t// Support: IE <=8\n\t\t\t\t// Exclude object elements\n\t\t\t\t} else if ( context.nodeName.toLowerCase() !== \"object\" ) {\n\n\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\tif ( (nid = context.getAttribute( \"id\" )) ) {\n\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", (nid = expando) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = \"#\" + nid + \" \" + toSelector( groups[i] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\t\t\t\t}\n\n\t\t\t\tif ( newSelector ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement(\"fieldset\");\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\t// Known :disabled false positives:\n\t// IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset)\n\t// not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Check form elements and option elements for explicit disabling\n\t\treturn \"label\" in elem && elem.disabled === disabled ||\n\t\t\t\"form\" in elem && elem.disabled === disabled ||\n\n\t\t\t// Check non-disabled form elements for fieldset[disabled] ancestors\n\t\t\t\"form\" in elem && elem.disabled === false && (\n\t\t\t\t// Support: IE6-11+\n\t\t\t\t// Ancestry is covered for us\n\t\t\t\telem.isDisabled === disabled ||\n\n\t\t\t\t// Otherwise, assume any non-<option> under fieldset[disabled] is disabled\n\t\t\t\t/* jshint -W018 */\n\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\t(\"label\" in elem || !disabledAncestor( elem )) !== disabled\n\t\t\t);\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9-11, Edge\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\tif ( preferredDoc !== document &&\n\t\t(subWindow = document.defaultView) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( el ) {\n\t\tel.appendChild( document.createComment(\"\") );\n\t\treturn !el.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\treturn m ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( document.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( el ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll(\":enabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll(\":disabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( el ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === document ? -1 :\n\t\t\t\tb === document ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!compilerCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn (sel + \"\").replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( (oldCache = uniqueCache[ key ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context === document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\tif ( !context && elem.ownerDocument !== document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( el ) {\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement(\"fieldset\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( el ) {\n\treturn el.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;\n\t} );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn elem.contentDocument || jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnotwhite = ( /\\S+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( jQuery.isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && jQuery.type( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && jQuery.isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Support: Android 4.0 only\n\t\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\t\tresolve.call( undefined, value );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.call( undefined, value );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( jQuery.isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tjQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlen ? fn( elems[ 0 ], key ) : emptyGet;\n};\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ jQuery.camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ jQuery.camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( jQuery.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( jQuery.camelCase );\n\t\t\t} else {\n\t\t\t\tkey = jQuery.camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnotwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? JSON.parse( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tjQuery.contains( elem.ownerDocument, elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\nvar swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted,\n\t\tscale = 1,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\tdo {\n\n\t\t\t// If previous iteration zeroed out, double until we get *something*.\n\t\t\t// Use string for doubling so we don't accidentally see scale as unchanged below\n\t\t\tscale = scale || \".5\";\n\n\t\t\t// Adjust and apply\n\t\t\tinitialInUnit = initialInUnit / scale;\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t// Break the loop if scale is unchanged or perfect, or if we've just had enough.\n\t\t} while (\n\t\t\tscale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations\n\t\t);\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) ),\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i );\n\nvar rscriptType = ( /^$|\\/(?:java|ecma)script/i );\n\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// Support: IE <=9 only\n\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\n// Support: IE <=9 only\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret = typeof context.getElementsByTagName !== \"undefined\" ?\n\t\t\tcontext.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== \"undefined\" ?\n\t\t\t\tcontext.querySelectorAll( tag || \"*\" ) :\n\t\t\t[];\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], ret ) :\n\t\tret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, contains, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( contains ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n} )();\nvar documentElement = document.documentElement;\n\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 only\n// See #13393 for more info\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tvar event = jQuery.event.fix( nativeEvent );\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\t\t\thandlers = ( dataPriv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or 2) have namespace(s)\n\t\t\t\t// a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, matches, sel, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Support: IE <=9\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t//\n\t\t// Support: Firefox <=42\n\t\t// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)\n\t\tif ( delegateCount && cur.nodeType &&\n\t\t\t( event.type !== \"click\" || isNaN( event.button ) || event.button < 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== \"click\" ) ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matches } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: jQuery.isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\tthis.focus();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this.type === \"checkbox\" && this.click && jQuery.nodeName( this, \"input\" ) ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\treturn ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t/* eslint-disable max-len */\n\n\t// See https://github.com/eslint/eslint/issues/3229\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n\n\t/* eslint-enable */\n\n\t// Support: IE <=10 - 11, Edge 12 - 13\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\nfunction manipulationTarget( elem, content ) {\n\tif ( jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn elem.getElementsByTagName( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\n\tif ( match ) {\n\t\telem.type = match[ 1 ];\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.access( src );\n\t\tpdataCur = dataPriv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = concat.apply( [], args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tisFunction = jQuery.isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( isFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( isFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && jQuery.contains( node.ownerDocument, node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html.replace( rxhtmlTag, \"<$1></$2>\" );\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rmargin = ( /^margin/ );\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdiv.style.cssText =\n\t\t\t\"box-sizing:border-box;\" +\n\t\t\t\"position:relative;display:block;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"top:1%;width:50%\";\n\t\tdiv.innerHTML = \"\";\n\t\tdocumentElement.appendChild( container );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = divStyle.marginLeft === \"2px\";\n\t\tboxSizingReliableVal = divStyle.width === \"4px\";\n\n\t\t// Support: Android 4.0 - 4.3 only\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.marginRight = \"50%\";\n\t\tpixelMarginRightVal = divStyle.marginRight === \"4px\";\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tcontainer.style.cssText = \"border:0;width:8px;height:0;top:0;left:-9999px;\" +\n\t\t\"padding:0;margin-top:1px;position:absolute\";\n\tcontainer.appendChild( div );\n\n\tjQuery.extend( support, {\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelMarginRight: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelMarginRightVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// Support: IE <=9 only\n\t// getPropertyValue is only needed for .css('filter') (#12537)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style;\n\n// Return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( name ) {\n\n\t// Shortcut for names that are not vendor prefixed\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// At this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\n\t\t\t// At this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// At this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar val,\n\t\tvalueIsBorderBox = true,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// Support: IE <=11 only\n\t// Running getBoundingClientRect on a disconnected node\n\t// in IE throws an error.\n\tif ( elem.getClientRects().length ) {\n\t\tval = elem.getBoundingClientRect()[ name ];\n\t}\n\n\t// Some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test( val ) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// Check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox &&\n\t\t\t( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// Use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t\"float\": \"cssFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] ||\n\t\t\t( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\tif ( type === \"number\" ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tstyle[ name ] = value;\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] ||\n\t\t\t( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = extra && getStyles( elem ),\n\t\t\t\tsubtract = extra && augmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t);\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ name ] = value;\n\t\t\t\tvalue = jQuery.css( elem, name );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 &&\n\t\t\t\t( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction raf() {\n\tif ( timerId ) {\n\t\twindow.requestAnimationFrame( raf );\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 13\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( jQuery.isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tjQuery.proxy( result.stop, result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnotwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off or if document is hidden\n\tif ( jQuery.fx.off || document.hidden ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\topt.duration = typeof opt.duration === \"number\" ?\n\t\t\topt.duration : opt.duration in jQuery.fx.speeds ?\n\t\t\t\tjQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = window.requestAnimationFrame ?\n\t\t\twindow.requestAnimationFrame( raf ) :\n\t\t\twindow.setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tif ( window.cancelAnimationFrame ) {\n\t\twindow.cancelAnimationFrame( timerId );\n\t} else {\n\t\twindow.clearInterval( timerId );\n\t}\n\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tjQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\t\trclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t\t0 :\n\t\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( typeof value === \"string\" && value ) {\n\t\t\tclasses = value.match( rnotwhite ) || [];\n\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 &&\n\t\t\t\t\t( \" \" + curValue + \" \" ).replace( rclass, \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tif ( typeof value === \"string\" && value ) {\n\t\t\tclasses = value.match( rnotwhite ) || [];\n\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 &&\n\t\t\t\t\t( \" \" + curValue + \" \" ).replace( rclass, \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( type === \"string\" ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + getClass( elem ) + \" \" ).replace( rclass, \" \" )\n\t\t\t\t\t.indexOf( className ) > -1\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g,\n\trspaces = /[\\x20\\t\\r\\n\\f]+/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\n\t\t\t\t\t// Handle most common string cases\n\t\t\t\t\tret.replace( rreturn, \"\" ) :\n\n\t\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) ).replace( rspaces, \" \" );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || {} )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\telem[ type ]();\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n} );\n\njQuery.fn.extend( {\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\n\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = jQuery.now();\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = jQuery.isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t} ) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 13\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in uncached url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rts, \"\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce++ ) + uncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" ).prop( {\n\t\t\t\t\tcharset: s.scriptCharset,\n\t\t\t\t\tsrc: s.url\n\t\t\t\t} ).on(\n\t\t\t\t\t\"load error\",\n\t\t\t\t\tcallback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = jQuery.trim( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar docElem, win, rect, doc,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\trect = elem.getBoundingClientRect();\n\n\t\t// Make sure element is not hidden (display: none)\n\t\tif ( rect.width || rect.height ) {\n\t\t\tdoc = elem.ownerDocument;\n\t\t\twin = getWindow( doc );\n\t\t\tdocElem = doc.documentElement;\n\n\t\t\treturn {\n\t\t\t\ttop: rect.top + win.pageYOffset - docElem.clientTop,\n\t\t\t\tleft: rect.left + win.pageXOffset - docElem.clientLeft\n\t\t\t};\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden elements (gh-2310)\n\t\treturn rect;\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// Fixed elements are offset from window (parentOffset = {top:0, left: 0},\n\t\t// because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume getBoundingClientRect is there when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset = {\n\t\t\t\ttop: parentOffset.top + jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true ),\n\t\t\t\tleft: parentOffset.left + jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true )\n\t\t\t};\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t}\n} );\n\njQuery.parseJSON = JSON.parse;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( !noGlobal ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "docs/_static/jquery-3.2.1.js",
    "content": "/*!\n * jQuery JavaScript Library v3.2.1\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2017-03-20T18:59Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar document = window.document;\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\n\n\n\tfunction DOMEval( code, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar script = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.2.1\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android <=4.0 only\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && Array.isArray( src ) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject( src ) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type( obj ) === \"function\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\n\t\t// As of jQuery 3.0, isNumeric is limited to\n\t\t// strings and numbers (primitives or objects)\n\t\t// that can be coerced to finite numbers (gh-2662)\n\t\tvar type = jQuery.type( obj );\n\t\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t\t// subtraction forces infinities to NaN\n\t\t\t!isNaN( obj - parseFloat( obj ) );\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\n\t\t/* eslint-disable no-unused-vars */\n\t\t// See https://github.com/eslint/eslint/issues/6125\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\n\t\t// Support: Android <=2.3 only (functionish RegExp)\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code ) {\n\t\tDOMEval( code );\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Support: IE <=9 - 11, Edge 12 - 13\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android <=4.0 only\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar tmp, args, proxy;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: Date.now,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.3\n * https://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2016-08-08\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tdisabledAncestor = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && (\"form\" in elem || \"label\" in elem);\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\n\t\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\t\tsetDocument( context );\n\t\t}\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( (m = match[1]) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( (elem = context.getElementById( m )) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && (elem = newContext.getElementById( m )) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[2] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!compilerCache[ selector + \" \" ] &&\n\t\t\t\t(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\n\t\t\t\tif ( nodeType !== 1 ) {\n\t\t\t\t\tnewContext = context;\n\t\t\t\t\tnewSelector = selector;\n\n\t\t\t\t// qSA looks outside Element context, which is not what we want\n\t\t\t\t// Thanks to Andrew Dupont for this workaround technique\n\t\t\t\t// Support: IE <=8\n\t\t\t\t// Exclude object elements\n\t\t\t\t} else if ( context.nodeName.toLowerCase() !== \"object\" ) {\n\n\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\tif ( (nid = context.getAttribute( \"id\" )) ) {\n\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", (nid = expando) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = \"#\" + nid + \" \" + toSelector( groups[i] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\t\t\t\t}\n\n\t\t\t\tif ( newSelector ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement(\"fieldset\");\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\t\tdisabledAncestor( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9-11, Edge\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\tif ( preferredDoc !== document &&\n\t\t(subWindow = document.defaultView) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( el ) {\n\t\tel.appendChild( document.createComment(\"\") );\n\t\treturn !el.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t});\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( (elem = elems[i++]) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( document.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( el ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll(\":enabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll(\":disabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( el ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === document ? -1 :\n\t\t\t\tb === document ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!compilerCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn (sel + \"\").replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( (oldCache = uniqueCache[ key ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context === document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\tif ( !context && elem.ownerDocument !== document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( el ) {\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement(\"fieldset\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( el ) {\n\treturn el.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n};\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Simple selector that can be filtered directly, removing non-Elements\n\tif ( risSimple.test( qualifier ) ) {\n\t\treturn jQuery.filter( qualifier, elements, not );\n\t}\n\n\t// Complex selector, compare the two sets, removing non-Elements\n\tqualifier = jQuery.filter( qualifier, elements );\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;\n\t} );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n        if ( nodeName( elem, \"iframe\" ) ) {\n            return elem.contentDocument;\n        }\n\n        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n        // Treat the template element as a regular one in browsers that\n        // don't support it.\n        if ( nodeName( elem, \"template\" ) ) {\n            elem = elem.content || elem;\n        }\n\n        return jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( jQuery.isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && jQuery.type( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && jQuery.isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( jQuery.isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tjQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ jQuery.camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ jQuery.camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( jQuery.camelCase );\n\t\t\t} else {\n\t\t\t\tkey = jQuery.camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tjQuery.contains( elem.ownerDocument, elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\nvar swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted,\n\t\tscale = 1,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\tdo {\n\n\t\t\t// If previous iteration zeroed out, double until we get *something*.\n\t\t\t// Use string for doubling so we don't accidentally see scale as unchanged below\n\t\t\tscale = scale || \".5\";\n\n\t\t\t// Adjust and apply\n\t\t\tinitialInUnit = initialInUnit / scale;\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t// Break the loop if scale is unchanged or perfect, or if we've just had enough.\n\t\t} while (\n\t\t\tscale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations\n\t\t);\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i );\n\nvar rscriptType = ( /^$|\\/(?:java|ecma)script/i );\n\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// Support: IE <=9 only\n\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\n// Support: IE <=9 only\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, contains, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( contains ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n} )();\nvar documentElement = document.documentElement;\n\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 only\n// See #13393 for more info\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tvar event = jQuery.event.fix( nativeEvent );\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\t\t\thandlers = ( dataPriv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or 2) have namespace(s)\n\t\t\t\t// a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: jQuery.isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\tthis.focus();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this.type === \"checkbox\" && this.click && nodeName( this, \"input\" ) ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\tif ( button & 1 ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ( button & 2 ) {\n\t\t\t\treturn 3;\n\t\t\t}\n\n\t\t\tif ( button & 4 ) {\n\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t/* eslint-disable max-len */\n\n\t// See https://github.com/eslint/eslint/issues/3229\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n\n\t/* eslint-enable */\n\n\t// Support: IE <=10 - 11, Edge 12 - 13\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( \">tbody\", elem )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\n\tif ( match ) {\n\t\telem.type = match[ 1 ];\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.access( src );\n\t\tpdataCur = dataPriv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = concat.apply( [], args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tisFunction = jQuery.isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( isFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( isFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && jQuery.contains( node.ownerDocument, node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html.replace( rxhtmlTag, \"<$1></$2>\" );\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rmargin = ( /^margin/ );\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdiv.style.cssText =\n\t\t\t\"box-sizing:border-box;\" +\n\t\t\t\"position:relative;display:block;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"top:1%;width:50%\";\n\t\tdiv.innerHTML = \"\";\n\t\tdocumentElement.appendChild( container );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = divStyle.marginLeft === \"2px\";\n\t\tboxSizingReliableVal = divStyle.width === \"4px\";\n\n\t\t// Support: Android 4.0 - 4.3 only\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.marginRight = \"50%\";\n\t\tpixelMarginRightVal = divStyle.marginRight === \"4px\";\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tcontainer.style.cssText = \"border:0;width:8px;height:0;top:0;left:-9999px;\" +\n\t\t\"padding:0;margin-top:1px;position:absolute\";\n\tcontainer.appendChild( div );\n\n\tjQuery.extend( support, {\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelMarginRight: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelMarginRightVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style;\n\n// Return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( name ) {\n\n\t// Shortcut for names that are not vendor prefixed\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a property mapped along what jQuery.cssProps suggests or to\n// a vendor prefixed property.\nfunction finalPropName( name ) {\n\tvar ret = jQuery.cssProps[ name ];\n\tif ( !ret ) {\n\t\tret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;\n\t}\n\treturn ret;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i,\n\t\tval = 0;\n\n\t// If we already have the right measurement, avoid augmentation\n\tif ( extra === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\ti = 4;\n\n\t// Otherwise initialize for horizontal or vertical properties\n\t} else {\n\t\ti = name === \"width\" ? 1 : 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// At this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\n\t\t\t// At this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// At this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with computed style\n\tvar valueIsBorderBox,\n\t\tstyles = getStyles( elem ),\n\t\tval = curCSS( elem, name, styles ),\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// Computed unit is not pixels. Stop here and return.\n\tif ( rnumnonpx.test( val ) ) {\n\t\treturn val;\n\t}\n\n\t// Check for style in case a browser which returns unreliable values\n\t// for getComputedStyle silently falls back to the reliable elem.style\n\tvalueIsBorderBox = isBorderBox &&\n\t\t( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t// Fall back to offsetWidth/Height when value is \"auto\"\n\t// This happens for inline elements with no explicit setting (gh-3571)\n\tif ( val === \"auto\" ) {\n\t\tval = elem[ \"offset\" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];\n\t}\n\n\t// Normalize \"\", auto, and prepare for extra\n\tval = parseFloat( val ) || 0;\n\n\t// Use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t\"float\": \"cssFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\tif ( type === \"number\" ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = extra && getStyles( elem ),\n\t\t\t\tsubtract = extra && augmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t);\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ name ] = value;\n\t\t\t\tvalue = jQuery.css( elem, name );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 &&\n\t\t\t\t( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 13\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( jQuery.isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tjQuery.proxy( result.stop, result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( typeof value === \"string\" && value ) {\n\t\t\tclasses = value.match( rnothtmlwhite ) || [];\n\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tif ( typeof value === \"string\" && value ) {\n\t\t\tclasses = value.match( rnothtmlwhite ) || [];\n\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( type === \"string\" ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = value.match( rnothtmlwhite ) || [];\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || {} )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\telem[ type ]();\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n} );\n\njQuery.fn.extend( {\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\n\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = jQuery.now();\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = jQuery.isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 13\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce++ ) + uncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" ).prop( {\n\t\t\t\t\tcharset: s.scriptCharset,\n\t\t\t\t\tsrc: s.url\n\t\t\t\t} ).on(\n\t\t\t\t\t\"load error\",\n\t\t\t\t\tcallback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar doc, docElem, rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\trect = elem.getBoundingClientRect();\n\n\t\tdoc = elem.ownerDocument;\n\t\tdocElem = doc.documentElement;\n\t\twin = doc.defaultView;\n\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset - docElem.clientTop,\n\t\t\tleft: rect.left + win.pageXOffset - docElem.clientLeft\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// Fixed elements are offset from window (parentOffset = {top:0, left: 0},\n\t\t// because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume getBoundingClientRect is there when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset = {\n\t\t\t\ttop: parentOffset.top + jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true ),\n\t\t\t\tleft: parentOffset.left + jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true )\n\t\t\t};\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t}\n} );\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( !noGlobal ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "docs/_static/jquery-3.4.1.js",
    "content": "/*!\n * jQuery JavaScript Library v3.4.1\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2019-05-01T21:04Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar document = window.document;\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n      // Support: Chrome <=57, Firefox <=52\n      // In some browsers, typeof returns \"function\" for HTML <object> elements\n      // (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n      // We don't want to classify *any* DOM node as a function.\n      return typeof obj === \"function\" && typeof obj.nodeType !== \"number\";\n  };\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.4.1\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android <=4.0 only\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code, options ) {\n\t\tDOMEval( code, { nonce: options && options.nonce } );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android <=4.0 only\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.4\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2019-04-08\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\n\t\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\t\tsetDocument( context );\n\t\t}\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( (m = match[1]) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( (elem = context.getElementById( m )) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && (elem = newContext.getElementById( m )) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[2] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t(!rbuggyQSA || !rbuggyQSA.test( selector )) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t(nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\") ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 && rdescend.test( selector ) ) {\n\n\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\tif ( (nid = context.getAttribute( \"id\" )) ) {\n\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", (nid = expando) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = \"#\" + nid + \" \" + toSelector( groups[i] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement(\"fieldset\");\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem.namespaceURI,\n\t\tdocElem = (elem.ownerDocument || elem).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9-11, Edge\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\tif ( preferredDoc !== document &&\n\t\t(subWindow = document.defaultView) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( el ) {\n\t\tel.appendChild( document.createComment(\"\") );\n\t\treturn !el.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t});\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( (elem = elems[i++]) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( document.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( el ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll(\":enabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll(\":disabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( el ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === document ? -1 :\n\t\t\t\tb === document ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn (sel + \"\").replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( (oldCache = uniqueCache[ key ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context === document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\tif ( !context && elem.ownerDocument !== document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( el ) {\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement(\"fieldset\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( el ) {\n\treturn el.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n};\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( typeof elem.contentDocument !== \"undefined\" ) {\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\nvar swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// Support: IE <=9 only\n\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\n// Support: IE <=9 only\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n} )();\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tvar event = jQuery.event.fix( nativeEvent );\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\t\t\thandlers = ( dataPriv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\treturn result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\tif ( button & 1 ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ( button & 2 ) {\n\t\t\t\treturn 3;\n\t\t\t}\n\n\t\t\tif ( button & 4 ) {\n\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t/* eslint-disable max-len */\n\n\t// See https://github.com/eslint/eslint/issues/3229\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n\n\t/* eslint-enable */\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.access( src );\n\t\tpdataCur = dataPriv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = concat.apply( [], args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html.replace( rxhtmlTag, \"<$1></$2>\" );\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t// This happens for inline elements with no explicit setting (gh-3571)\n\t// Support: Android <=4.1 - 4.3 only\n\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t// Support: IE 9-11 only\n\t// Also use offsetWidth/offsetHeight for when box sizing is unreliable\n\t// We use getClientRects() to check for hidden/disconnected.\n\t// In those cases, the computed value can be trusted to be border-box\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\t\tval === \"auto\" ||\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || {} )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = Date.now();\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce++ ) + uncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\n\njQuery._evalUrl = function( url, options ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( \"load error\", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n} );\n\njQuery.fn.extend( {\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t}\n} );\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( !noGlobal ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "docs/_static/jquery-3.5.1.js",
    "content": "/*!\n * jQuery JavaScript Library v3.5.1\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2020-05-04T22:49Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar flat = arr.flat ? function( array ) {\n\treturn arr.flat.call( array );\n} : function( array ) {\n\treturn arr.concat.apply( [], array );\n};\n\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n      // Support: Chrome <=57, Firefox <=52\n      // In some browsers, typeof returns \"function\" for HTML <object> elements\n      // (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n      // We don't want to classify *any* DOM node as a function.\n      return typeof obj === \"function\" && typeof obj.nodeType !== \"number\";\n  };\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\nvar document = window.document;\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.5.1\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teven: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn ( i + 1 ) % 2;\n\t\t} ) );\n\t},\n\n\todd: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn i % 2;\n\t\t} ) );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a provided context; falls back to the global one\n\t// if not specified.\n\tglobalEval: function( code, options, doc ) {\n\t\tDOMEval( code, { nonce: options && options.nonce }, doc );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn flat( ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( _i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.5\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2020-03-14\n */\n( function( window ) {\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ( {} ).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpushNative = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|\" +\n\t\t\"ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram\n\tidentifier = \"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace +\n\t\t\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\n\t\t// \"Attribute values must be CSS identifiers [capture 5]\n\t\t// or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" +\n\t\twhitespace + \"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" +\n\t\twhitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace +\n\t\t\"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" +\n\t\t\twhitespace + \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" +\n\t\t\twhitespace + \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace +\n\t\t\t\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n\t\t\t\"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace + \"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\", \"g\" ),\n\tfunescape = function( escape, nonHex ) {\n\t\tvar high = \"0x\" + escape.slice( 1 ) - 0x10000;\n\n\t\treturn nonHex ?\n\n\t\t\t// Strip the backslash prefix from a non-hex escape sequence\n\t\t\tnonHex :\n\n\t\t\t// Replace a hexadecimal escape sequence with the encoded Unicode code point\n\t\t\t// Support: IE <=11+\n\t\t\t// For values outside the Basic Multilingual Plane (BMP), manually construct a\n\t\t\t// surrogate pair\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" +\n\t\t\t\tch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t( arr = slice.call( preferredDoc.childNodes ) ),\n\t\tpreferredDoc.childNodes\n\t);\n\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\t// eslint-disable-next-line no-unused-expressions\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpushNative.apply( target, slice.call( els ) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( ( target[ j++ ] = els[ i++ ] ) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\t\tsetDocument( context );\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( ( m = match[ 1 ] ) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( ( elem = context.getElementById( m ) ) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && ( elem = newContext.getElementById( m ) ) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[ 2 ] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t( nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\" ) ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// The technique has to be used as well when a leading combinator is used\n\t\t\t\t// as such selectors are not recognized by querySelectorAll.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 &&\n\t\t\t\t\t( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\n\t\t\t\t\t// We can use :scope instead of the ID hack if the browser\n\t\t\t\t\t// supports it & if we're not changing the context.\n\t\t\t\t\tif ( newContext !== context || !support.scope ) {\n\n\t\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\t\tif ( ( nid = context.getAttribute( \"id\" ) ) ) {\n\t\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontext.setAttribute( \"id\", ( nid = expando ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[ i ] = ( nid ? \"#\" + nid : \":scope\" ) + \" \" +\n\t\t\t\t\t\t\ttoSelector( groups[ i ] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn ( cache[ key + \" \" ] = value );\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement( \"fieldset\" );\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch ( e ) {\n\t\treturn false;\n\t} finally {\n\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split( \"|\" ),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[ i ] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( ( cur = cur.nextSibling ) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn ( name === \"input\" || name === \"button\" ) && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction( function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction( function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ ( j = matchIndexes[ i ] ) ] ) {\n\t\t\t\t\tseed[ j ] = !( matches[ j ] = seed[ j ] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem.namespaceURI,\n\t\tdocElem = ( elem.ownerDocument || elem ).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( preferredDoc != document &&\n\t\t( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,\n\t// Safari 4 - 5 only, Opera <=11.6 - 12.x only\n\t// IE/Edge & older browsers don't support the :scope pseudo-class.\n\t// Support: Safari 6.0 only\n\t// Safari 6.0 supports :scope but it's an alias of :root there.\n\tsupport.scope = assert( function( el ) {\n\t\tdocElem.appendChild( el ).appendChild( document.createElement( \"div\" ) );\n\t\treturn typeof el.querySelectorAll !== \"undefined\" &&\n\t\t\t!el.querySelectorAll( \":scope fieldset div\" ).length;\n\t} );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert( function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute( \"className\" );\n\t} );\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert( function( el ) {\n\t\tel.appendChild( document.createComment( \"\" ) );\n\t\treturn !el.getElementsByTagName( \"*\" ).length;\n\t} );\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert( function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t} );\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[ \"ID\" ] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute( \"id\" ) === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[ \"ID\" ] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode( \"id\" );\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( ( elem = elems[ i++ ] ) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[ \"TAG\" ] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[ \"CLASS\" ] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {\n\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert( function( el ) {\n\n\t\t\tvar input;\n\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll( \"[msallowcapture^='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll( \"[selected]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"~=\" );\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 15 - 18+\n\t\t\t// IE 11/Edge don't find elements on a `[name='']` query in some cases.\n\t\t\t// Adding a temporary attribute to the document before the selection works\n\t\t\t// around the issue.\n\t\t\t// Interestingly, IE 10 & older don't seem to have the issue.\n\t\t\tinput = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"name\", \"\" );\n\t\t\tel.appendChild( input );\n\t\t\tif ( !el.querySelectorAll( \"[name='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*name\" + whitespace + \"*=\" +\n\t\t\t\t\twhitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll( \":checked\" ).length ) {\n\t\t\t\trbuggyQSA.push( \":checked\" );\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push( \".#.+[+~]\" );\n\t\t\t}\n\n\t\t\t// Support: Firefox <=3.6 - 5 only\n\t\t\t// Old Firefox doesn't throw on a badly-escaped identifier.\n\t\t\tel.querySelectorAll( \"\\\\\\f\" );\n\t\t\trbuggyQSA.push( \"[\\\\r\\\\n\\\\f]\" );\n\t\t} );\n\n\t\tassert( function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll( \"[name=d]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll( \":enabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll( \":disabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: Opera 10 - 11 only\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll( \"*,:x\" );\n\t\t\trbuggyQSA.push( \",.*:\" );\n\t\t} );\n\t}\n\n\tif ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector ) ) ) ) {\n\n\t\tassert( function( el ) {\n\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t} );\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( \"|\" ) );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( \"|\" ) );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t) );\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( ( b = b.parentNode ) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t// two documents; shallow comparisons work.\n\t\t// eslint-disable-next-line eqeqeq\n\t\tcompare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( a == document || a.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, a ) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( b == document || b.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, b ) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\treturn a == document ? -1 :\n\t\t\t\tb == document ? 1 :\n\t\t\t\t/* eslint-enable eqeqeq */\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[ i ] === bp[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[ i ], bp[ i ] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\tap[ i ] == preferredDoc ? -1 :\n\t\t\tbp[ i ] == preferredDoc ? 1 :\n\t\t\t/* eslint-enable eqeqeq */\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\tsetDocument( elem );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\n\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t// fragment in IE 9\n\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( context.ownerDocument || context ) != document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( elem.ownerDocument || elem ) != document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn ( sel + \"\" ).replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( ( node = elem[ i++ ] ) ) {\n\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[ 1 ] = match[ 1 ].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[ 3 ] = ( match[ 3 ] || match[ 4 ] ||\n\t\t\t\tmatch[ 5 ] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[ 2 ] === \"~=\" ) {\n\t\t\t\tmatch[ 3 ] = \" \" + match[ 3 ] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[ 1 ] = match[ 1 ].toLowerCase();\n\n\t\t\tif ( match[ 1 ].slice( 0, 3 ) === \"nth\" ) {\n\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[ 3 ] ) {\n\t\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[ 4 ] = +( match[ 4 ] ?\n\t\t\t\t\tmatch[ 5 ] + ( match[ 6 ] || 1 ) :\n\t\t\t\t\t2 * ( match[ 3 ] === \"even\" || match[ 3 ] === \"odd\" ) );\n\t\t\t\tmatch[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === \"odd\" );\n\n\t\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[ 3 ] ) {\n\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[ 6 ] && match[ 2 ];\n\n\t\t\tif ( matchExpr[ \"CHILD\" ].test( match[ 0 ] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[ 3 ] ) {\n\t\t\t\tmatch[ 2 ] = match[ 4 ] || match[ 5 ] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t( excess = tokenize( unquoted, true ) ) &&\n\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t( excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length ) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[ 0 ] = match[ 0 ].slice( 0, excess );\n\t\t\t\tmatch[ 2 ] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() {\n\t\t\t\t\treturn true;\n\t\t\t\t} :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t( pattern = new RegExp( \"(^|\" + whitespace +\n\t\t\t\t\t\")\" + className + \"(\" + whitespace + \"|$)\" ) ) && classCache(\n\t\t\t\t\t\tclassName, function( elem ) {\n\t\t\t\t\t\t\treturn pattern.test(\n\t\t\t\t\t\t\t\ttypeof elem.className === \"string\" && elem.className ||\n\t\t\t\t\t\t\t\ttypeof elem.getAttribute !== \"undefined\" &&\n\t\t\t\t\t\t\t\t\telem.getAttribute( \"class\" ) ||\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\t/* eslint-disable max-len */\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t\t/* eslint-enable max-len */\n\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, _argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( ( node = node[ dir ] ) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction( function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[ i ] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} ) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction( function( selector ) {\n\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction( function( seed, matches, _context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\t\t\t\t\tseed[ i ] = !( matches[ i ] = elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} ) :\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tinput[ 0 ] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[ 0 ] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t} ),\n\n\t\t\"has\": markFunction( function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t} ),\n\n\t\t\"contains\": markFunction( function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t} ),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test( lang || \"\" ) ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( ( elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute( \"xml:lang\" ) || elem.getAttribute( \"lang\" ) ) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t} ),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement &&\n\t\t\t\t( !document.hasFocus || document.hasFocus() ) &&\n\t\t\t\t!!( elem.type || elem.href || ~elem.tabIndex );\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn ( nodeName === \"input\" && !!elem.checked ) ||\n\t\t\t\t( nodeName === \"option\" && !!elem.selected );\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\t// eslint-disable-next-line no-unused-expressions\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[ \"empty\" ]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( ( attr = elem.getAttribute( \"type\" ) ) == null ||\n\t\t\t\t\tattr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo( function() {\n\t\t\treturn [ 0 ];\n\t\t} ),\n\n\t\t\"last\": createPositionalPseudo( function( _matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t} ),\n\n\t\t\"eq\": createPositionalPseudo( function( _matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t} ),\n\n\t\t\"even\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"odd\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"lt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"gt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} )\n\t}\n};\n\nExpr.pseudos[ \"nth\" ] = Expr.pseudos[ \"eq\" ];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || ( match = rcomma.exec( soFar ) ) ) {\n\t\t\tif ( match ) {\n\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[ 0 ].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( ( tokens = [] ) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( ( match = rcombinators.exec( soFar ) ) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push( {\n\t\t\t\tvalue: matched,\n\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[ 0 ].replace( rtrim, \" \" )\n\t\t\t} );\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||\n\t\t\t\t( match = preFilters[ type ]( match ) ) ) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push( {\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t} );\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[ i ].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || ( elem[ expando ] = {} );\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] ||\n\t\t\t\t\t\t\t( outerCache[ elem.uniqueID ] = {} );\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( ( oldCache = uniqueCache[ key ] ) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn ( newCache[ 2 ] = oldCache[ 2 ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[ i ]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[ 0 ];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[ i ], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction( function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts(\n\t\t\t\tselector || \"*\",\n\t\t\t\tcontext.nodeType ? [ context ] : context,\n\t\t\t\t[]\n\t\t\t),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( ( elem = temp[ i ] ) ) {\n\t\t\t\t\tmatcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) ) {\n\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( ( matcherIn[ i ] = elem ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, ( matcherOut = [] ), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) &&\n\t\t\t\t\t\t( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {\n\n\t\t\t\t\t\tseed[ temp ] = !( results[ temp ] = elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t} );\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[ 0 ].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[ \" \" ],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t( checkContext = context ).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[ j ].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\n\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\ttokens\n\t\t\t\t\t\t.slice( 0, i - 1 )\n\t\t\t\t\t\t.concat( { value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" } )\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[ \"TAG\" ]( \"*\", outermost ),\n\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\n\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\toutermostContext = context == document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\n\t\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\t\tif ( !context && elem.ownerDocument != document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( ( matcher = elementMatchers[ j++ ] ) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( ( elem = !matcher && elem ) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( ( matcher = setMatchers[ j++ ] ) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !( unmatched[ i ] || setMatched[ i ] ) ) {\n\t\t\t\t\t\t\t\tsetMatched[ i ] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[ i ] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache(\n\t\t\tselector,\n\t\t\tmatcherFromGroupMatchers( elementMatchers, setMatchers )\n\t\t);\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( ( selector = compiled.selector || selector ) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[ 0 ] = match[ 0 ].slice( 0 );\n\t\tif ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === \"ID\" &&\n\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {\n\n\t\t\tcontext = ( Expr.find[ \"ID\" ]( token.matches[ 0 ]\n\t\t\t\t.replace( runescape, funescape ), context ) || [] )[ 0 ];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[ \"needsContext\" ].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[ i ];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ ( type = token.type ) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( ( find = Expr.find[ type ] ) ) {\n\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( ( seed = find(\n\t\t\t\t\ttoken.matches[ 0 ].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext\n\t\t\t\t) ) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split( \"\" ).sort( sortOrder ).join( \"\" ) === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert( function( el ) {\n\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement( \"fieldset\" ) ) & 1;\n} );\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert( function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute( \"href\" ) === \"#\";\n} ) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert( function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n} ) ) {\n\taddHandle( \"value\", function( elem, _name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert( function( el ) {\n\treturn el.getAttribute( \"disabled\" ) == null;\n} ) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\t\tnull;\n\t\t}\n\t} );\n}\n\nreturn Sizzle;\n\n} )( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n};\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( elem.contentDocument != null &&\n\n\t\t\t// Support: IE 11+\n\t\t\t// <object> elements with no `data` attribute has an object\n\t\t\t// `contentDocument` with a `null` prototype.\n\t\t\tgetProto( elem.contentDocument ) ) {\n\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( _i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, _key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( _all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// Support: IE <=9 only\n\t// IE <=9 replaces <option> tags with their contents when inserted outside of\n\t// the select element.\n\tdiv.innerHTML = \"<option></option>\";\n\tsupport.option = !!div.lastChild;\n} )();\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: IE <=9 only\nif ( !support.option ) {\n\twrapMap.optgroup = wrapMap.option = [ 1, \"<select multiple='multiple'>\", \"</select>\" ];\n}\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Only attach events to objects that accept data\n\t\tif ( !acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = Object.create( null );\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\n\t\t\t// Make a writable jQuery.Event from the native event object\n\t\t\tevent = jQuery.event.fix( nativeEvent ),\n\n\t\t\thandlers = (\n\t\t\t\t\tdataPriv.get( this, \"events\" ) || Object.create( null )\n\t\t\t\t)[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\treturn result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\tif ( button & 1 ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ( button & 2 ) {\n\t\t\t\treturn 3;\n\t\t\t}\n\n\t\t\tif ( button & 4 ) {\n\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.get( src );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdataPriv.remove( dest, \"handle events\" );\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = flat( args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t}, doc );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html;\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.call( elem );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableTrDimensionsVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t},\n\n\t\t// Support: IE 9 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Behavior in IE 9 is more subtle than in newer versions & it passes\n\t\t// some versions of this test; make sure not to make it pass there!\n\t\treliableTrDimensions: function() {\n\t\t\tvar table, tr, trChild, trStyle;\n\t\t\tif ( reliableTrDimensionsVal == null ) {\n\t\t\t\ttable = document.createElement( \"table\" );\n\t\t\t\ttr = document.createElement( \"tr\" );\n\t\t\t\ttrChild = document.createElement( \"div\" );\n\n\t\t\t\ttable.style.cssText = \"position:absolute;left:-11111px\";\n\t\t\t\ttr.style.height = \"1px\";\n\t\t\t\ttrChild.style.height = \"9px\";\n\n\t\t\t\tdocumentElement\n\t\t\t\t\t.appendChild( table )\n\t\t\t\t\t.appendChild( tr )\n\t\t\t\t\t.appendChild( trChild );\n\n\t\t\t\ttrStyle = window.getComputedStyle( tr );\n\t\t\t\treliableTrDimensionsVal = parseInt( trStyle.height ) > 3;\n\n\t\t\t\tdocumentElement.removeChild( table );\n\t\t\t}\n\t\t\treturn reliableTrDimensionsVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( _elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Support: IE 9 - 11 only\n\t// Use offsetWidth/offsetHeight for when box sizing is unreliable.\n\t// In those cases, the computed value can be trusted to be border-box.\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\n\t\t// Support: IE 10 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Interestingly, in some cases IE 9 doesn't suffer from this issue.\n\t\t!support.reliableTrDimensions() && nodeName( elem, \"tr\" ) ||\n\n\t\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t\t// This happens for inline elements with no explicit setting (gh-3571)\n\t\tval === \"auto\" ||\n\n\t\t// Support: Android <=4.1 - 4.3 only\n\t\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\n\t\t// Make sure the element is visible & connected\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( _i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( _i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( _i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = (\n\t\t\t\t\tdataPriv.get( cur, \"events\" ) || Object.create( null )\n\t\t\t\t)[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\n\t\t\t\t// Handle: regular nodes (via `this.ownerDocument`), window\n\t\t\t\t// (via `this.document`) & document (via `this`).\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = { guid: Date.now() };\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( _i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce.guid++ ) +\n\t\t\t\t\tuncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Use a noop converter for missing script\n\t\t\tif ( !isSuccess && jQuery.inArray( \"script\", s.dataTypes ) > -1 ) {\n\t\t\t\ts.converters[ \"text script\" ] = function() {};\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( _i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\njQuery.ajaxPrefilter( function( s ) {\n\tvar i;\n\tfor ( i in s.headers ) {\n\t\tif ( i.toLowerCase() === \"content-type\" ) {\n\t\t\ts.contentType = s.headers[ i ] || \"\";\n\t\t}\n\t}\n} );\n\n\njQuery._evalUrl = function( url, options, doc ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options, doc );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( \"load error\", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce.guid++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tif ( typeof props.top === \"number\" ) {\n\t\t\t\tprops.top += \"px\";\n\t\t\t}\n\t\t\tif ( typeof props.left === \"number\" ) {\n\t\t\t\tprops.left += \"px\";\n\t\t\t}\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( _i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( _i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( _i, name ) {\n\n\t\t// Handle event binding\n\t\tjQuery.fn[ name ] = function( data, fn ) {\n\t\t\treturn arguments.length > 0 ?\n\t\t\t\tthis.on( name, null, data, fn ) :\n\t\t\t\tthis.trigger( name );\n\t\t};\n\t} );\n\n\n\n\n// Support: Android <=4.0 only\n// Make sure we trim BOM and NBSP\nvar rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\njQuery.trim = function( text ) {\n\treturn text == null ?\n\t\t\"\" :\n\t\t( text + \"\" ).replace( rtrim, \"\" );\n};\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === \"undefined\" ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "docs/_static/jquery-3.6.0.js",
    "content": "/*!\n * jQuery JavaScript Library v3.6.0\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright OpenJS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2021-03-02T17:08Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar flat = arr.flat ? function( array ) {\n\treturn arr.flat.call( array );\n} : function( array ) {\n\treturn arr.concat.apply( [], array );\n};\n\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n\t\t// Support: Chrome <=57, Firefox <=52\n\t\t// In some browsers, typeof returns \"function\" for HTML <object> elements\n\t\t// (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n\t\t// We don't want to classify *any* DOM node as a function.\n\t\t// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5\n\t\t// Plus for old WebKit, typeof returns \"function\" for HTML collections\n\t\t// (e.g., `typeof document.getElementsByTagName(\"div\") === \"function\"`). (gh-4756)\n\t\treturn typeof obj === \"function\" && typeof obj.nodeType !== \"number\" &&\n\t\t\ttypeof obj.item !== \"function\";\n\t};\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\nvar document = window.document;\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.6.0\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teven: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn ( i + 1 ) % 2;\n\t\t} ) );\n\t},\n\n\todd: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn i % 2;\n\t\t} ) );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a provided context; falls back to the global one\n\t// if not specified.\n\tglobalEval: function( code, options, doc ) {\n\t\tDOMEval( code, { nonce: options && options.nonce }, doc );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn flat( ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\n\tfunction( _i, name ) {\n\t\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n\t} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.6\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2021-02-16\n */\n( function( window ) {\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ( {} ).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpushNative = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|\" +\n\t\t\"ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram\n\tidentifier = \"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace +\n\t\t\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\n\t\t// \"Attribute values must be CSS identifiers [capture 5]\n\t\t// or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" +\n\t\twhitespace + \"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" +\n\t\twhitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace +\n\t\t\"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" +\n\t\t\twhitespace + \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" +\n\t\t\twhitespace + \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace +\n\t\t\t\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n\t\t\t\"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace + \"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\", \"g\" ),\n\tfunescape = function( escape, nonHex ) {\n\t\tvar high = \"0x\" + escape.slice( 1 ) - 0x10000;\n\n\t\treturn nonHex ?\n\n\t\t\t// Strip the backslash prefix from a non-hex escape sequence\n\t\t\tnonHex :\n\n\t\t\t// Replace a hexadecimal escape sequence with the encoded Unicode code point\n\t\t\t// Support: IE <=11+\n\t\t\t// For values outside the Basic Multilingual Plane (BMP), manually construct a\n\t\t\t// surrogate pair\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" +\n\t\t\t\tch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t( arr = slice.call( preferredDoc.childNodes ) ),\n\t\tpreferredDoc.childNodes\n\t);\n\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\t// eslint-disable-next-line no-unused-expressions\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpushNative.apply( target, slice.call( els ) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( ( target[ j++ ] = els[ i++ ] ) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\t\tsetDocument( context );\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( ( m = match[ 1 ] ) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( ( elem = context.getElementById( m ) ) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && ( elem = newContext.getElementById( m ) ) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[ 2 ] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t( nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\" ) ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// The technique has to be used as well when a leading combinator is used\n\t\t\t\t// as such selectors are not recognized by querySelectorAll.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 &&\n\t\t\t\t\t( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\n\t\t\t\t\t// We can use :scope instead of the ID hack if the browser\n\t\t\t\t\t// supports it & if we're not changing the context.\n\t\t\t\t\tif ( newContext !== context || !support.scope ) {\n\n\t\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\t\tif ( ( nid = context.getAttribute( \"id\" ) ) ) {\n\t\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontext.setAttribute( \"id\", ( nid = expando ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[ i ] = ( nid ? \"#\" + nid : \":scope\" ) + \" \" +\n\t\t\t\t\t\t\ttoSelector( groups[ i ] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn ( cache[ key + \" \" ] = value );\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement( \"fieldset\" );\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch ( e ) {\n\t\treturn false;\n\t} finally {\n\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split( \"|\" ),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[ i ] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( ( cur = cur.nextSibling ) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn ( name === \"input\" || name === \"button\" ) && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction( function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction( function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ ( j = matchIndexes[ i ] ) ] ) {\n\t\t\t\t\tseed[ j ] = !( matches[ j ] = seed[ j ] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem && elem.namespaceURI,\n\t\tdocElem = elem && ( elem.ownerDocument || elem ).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( preferredDoc != document &&\n\t\t( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,\n\t// Safari 4 - 5 only, Opera <=11.6 - 12.x only\n\t// IE/Edge & older browsers don't support the :scope pseudo-class.\n\t// Support: Safari 6.0 only\n\t// Safari 6.0 supports :scope but it's an alias of :root there.\n\tsupport.scope = assert( function( el ) {\n\t\tdocElem.appendChild( el ).appendChild( document.createElement( \"div\" ) );\n\t\treturn typeof el.querySelectorAll !== \"undefined\" &&\n\t\t\t!el.querySelectorAll( \":scope fieldset div\" ).length;\n\t} );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert( function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute( \"className\" );\n\t} );\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert( function( el ) {\n\t\tel.appendChild( document.createComment( \"\" ) );\n\t\treturn !el.getElementsByTagName( \"*\" ).length;\n\t} );\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert( function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t} );\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[ \"ID\" ] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute( \"id\" ) === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[ \"ID\" ] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode( \"id\" );\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( ( elem = elems[ i++ ] ) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[ \"TAG\" ] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[ \"CLASS\" ] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {\n\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert( function( el ) {\n\n\t\t\tvar input;\n\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll( \"[msallowcapture^='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll( \"[selected]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"~=\" );\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 15 - 18+\n\t\t\t// IE 11/Edge don't find elements on a `[name='']` query in some cases.\n\t\t\t// Adding a temporary attribute to the document before the selection works\n\t\t\t// around the issue.\n\t\t\t// Interestingly, IE 10 & older don't seem to have the issue.\n\t\t\tinput = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"name\", \"\" );\n\t\t\tel.appendChild( input );\n\t\t\tif ( !el.querySelectorAll( \"[name='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*name\" + whitespace + \"*=\" +\n\t\t\t\t\twhitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll( \":checked\" ).length ) {\n\t\t\t\trbuggyQSA.push( \":checked\" );\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push( \".#.+[+~]\" );\n\t\t\t}\n\n\t\t\t// Support: Firefox <=3.6 - 5 only\n\t\t\t// Old Firefox doesn't throw on a badly-escaped identifier.\n\t\t\tel.querySelectorAll( \"\\\\\\f\" );\n\t\t\trbuggyQSA.push( \"[\\\\r\\\\n\\\\f]\" );\n\t\t} );\n\n\t\tassert( function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll( \"[name=d]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll( \":enabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll( \":disabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: Opera 10 - 11 only\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll( \"*,:x\" );\n\t\t\trbuggyQSA.push( \",.*:\" );\n\t\t} );\n\t}\n\n\tif ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector ) ) ) ) {\n\n\t\tassert( function( el ) {\n\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t} );\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( \"|\" ) );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( \"|\" ) );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t) );\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( ( b = b.parentNode ) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t// two documents; shallow comparisons work.\n\t\t// eslint-disable-next-line eqeqeq\n\t\tcompare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( a == document || a.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, a ) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( b == document || b.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, b ) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\treturn a == document ? -1 :\n\t\t\t\tb == document ? 1 :\n\t\t\t\t/* eslint-enable eqeqeq */\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[ i ] === bp[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[ i ], bp[ i ] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\tap[ i ] == preferredDoc ? -1 :\n\t\t\tbp[ i ] == preferredDoc ? 1 :\n\t\t\t/* eslint-enable eqeqeq */\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\tsetDocument( elem );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\n\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t// fragment in IE 9\n\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( context.ownerDocument || context ) != document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( elem.ownerDocument || elem ) != document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn ( sel + \"\" ).replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( ( node = elem[ i++ ] ) ) {\n\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[ 1 ] = match[ 1 ].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[ 3 ] = ( match[ 3 ] || match[ 4 ] ||\n\t\t\t\tmatch[ 5 ] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[ 2 ] === \"~=\" ) {\n\t\t\t\tmatch[ 3 ] = \" \" + match[ 3 ] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[ 1 ] = match[ 1 ].toLowerCase();\n\n\t\t\tif ( match[ 1 ].slice( 0, 3 ) === \"nth\" ) {\n\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[ 3 ] ) {\n\t\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[ 4 ] = +( match[ 4 ] ?\n\t\t\t\t\tmatch[ 5 ] + ( match[ 6 ] || 1 ) :\n\t\t\t\t\t2 * ( match[ 3 ] === \"even\" || match[ 3 ] === \"odd\" ) );\n\t\t\t\tmatch[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === \"odd\" );\n\n\t\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[ 3 ] ) {\n\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[ 6 ] && match[ 2 ];\n\n\t\t\tif ( matchExpr[ \"CHILD\" ].test( match[ 0 ] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[ 3 ] ) {\n\t\t\t\tmatch[ 2 ] = match[ 4 ] || match[ 5 ] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t( excess = tokenize( unquoted, true ) ) &&\n\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t( excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length ) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[ 0 ] = match[ 0 ].slice( 0, excess );\n\t\t\t\tmatch[ 2 ] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() {\n\t\t\t\t\treturn true;\n\t\t\t\t} :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t( pattern = new RegExp( \"(^|\" + whitespace +\n\t\t\t\t\t\")\" + className + \"(\" + whitespace + \"|$)\" ) ) && classCache(\n\t\t\t\t\t\tclassName, function( elem ) {\n\t\t\t\t\t\t\treturn pattern.test(\n\t\t\t\t\t\t\t\ttypeof elem.className === \"string\" && elem.className ||\n\t\t\t\t\t\t\t\ttypeof elem.getAttribute !== \"undefined\" &&\n\t\t\t\t\t\t\t\t\telem.getAttribute( \"class\" ) ||\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\t/* eslint-disable max-len */\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t\t/* eslint-enable max-len */\n\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, _argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( ( node = node[ dir ] ) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction( function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[ i ] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} ) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction( function( selector ) {\n\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction( function( seed, matches, _context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\t\t\t\t\tseed[ i ] = !( matches[ i ] = elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} ) :\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tinput[ 0 ] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[ 0 ] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t} ),\n\n\t\t\"has\": markFunction( function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t} ),\n\n\t\t\"contains\": markFunction( function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t} ),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test( lang || \"\" ) ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( ( elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute( \"xml:lang\" ) || elem.getAttribute( \"lang\" ) ) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t} ),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement &&\n\t\t\t\t( !document.hasFocus || document.hasFocus() ) &&\n\t\t\t\t!!( elem.type || elem.href || ~elem.tabIndex );\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn ( nodeName === \"input\" && !!elem.checked ) ||\n\t\t\t\t( nodeName === \"option\" && !!elem.selected );\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\t// eslint-disable-next-line no-unused-expressions\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[ \"empty\" ]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( ( attr = elem.getAttribute( \"type\" ) ) == null ||\n\t\t\t\t\tattr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo( function() {\n\t\t\treturn [ 0 ];\n\t\t} ),\n\n\t\t\"last\": createPositionalPseudo( function( _matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t} ),\n\n\t\t\"eq\": createPositionalPseudo( function( _matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t} ),\n\n\t\t\"even\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"odd\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"lt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"gt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} )\n\t}\n};\n\nExpr.pseudos[ \"nth\" ] = Expr.pseudos[ \"eq\" ];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || ( match = rcomma.exec( soFar ) ) ) {\n\t\t\tif ( match ) {\n\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[ 0 ].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( ( tokens = [] ) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( ( match = rcombinators.exec( soFar ) ) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push( {\n\t\t\t\tvalue: matched,\n\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[ 0 ].replace( rtrim, \" \" )\n\t\t\t} );\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||\n\t\t\t\t( match = preFilters[ type ]( match ) ) ) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push( {\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t} );\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[ i ].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || ( elem[ expando ] = {} );\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] ||\n\t\t\t\t\t\t\t( outerCache[ elem.uniqueID ] = {} );\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( ( oldCache = uniqueCache[ key ] ) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn ( newCache[ 2 ] = oldCache[ 2 ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[ i ]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[ 0 ];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[ i ], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction( function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts(\n\t\t\t\tselector || \"*\",\n\t\t\t\tcontext.nodeType ? [ context ] : context,\n\t\t\t\t[]\n\t\t\t),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( ( elem = temp[ i ] ) ) {\n\t\t\t\t\tmatcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) ) {\n\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( ( matcherIn[ i ] = elem ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, ( matcherOut = [] ), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) &&\n\t\t\t\t\t\t( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {\n\n\t\t\t\t\t\tseed[ temp ] = !( results[ temp ] = elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t} );\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[ 0 ].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[ \" \" ],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t( checkContext = context ).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[ j ].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\n\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\ttokens\n\t\t\t\t\t\t.slice( 0, i - 1 )\n\t\t\t\t\t\t.concat( { value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" } )\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[ \"TAG\" ]( \"*\", outermost ),\n\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\n\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\toutermostContext = context == document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\n\t\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\t\tif ( !context && elem.ownerDocument != document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( ( matcher = elementMatchers[ j++ ] ) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( ( elem = !matcher && elem ) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( ( matcher = setMatchers[ j++ ] ) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !( unmatched[ i ] || setMatched[ i ] ) ) {\n\t\t\t\t\t\t\t\tsetMatched[ i ] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[ i ] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache(\n\t\t\tselector,\n\t\t\tmatcherFromGroupMatchers( elementMatchers, setMatchers )\n\t\t);\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( ( selector = compiled.selector || selector ) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[ 0 ] = match[ 0 ].slice( 0 );\n\t\tif ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === \"ID\" &&\n\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {\n\n\t\t\tcontext = ( Expr.find[ \"ID\" ]( token.matches[ 0 ]\n\t\t\t\t.replace( runescape, funescape ), context ) || [] )[ 0 ];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[ \"needsContext\" ].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[ i ];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ ( type = token.type ) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( ( find = Expr.find[ type ] ) ) {\n\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( ( seed = find(\n\t\t\t\t\ttoken.matches[ 0 ].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext\n\t\t\t\t) ) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split( \"\" ).sort( sortOrder ).join( \"\" ) === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert( function( el ) {\n\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement( \"fieldset\" ) ) & 1;\n} );\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert( function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute( \"href\" ) === \"#\";\n} ) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert( function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n} ) ) {\n\taddHandle( \"value\", function( elem, _name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert( function( el ) {\n\treturn el.getAttribute( \"disabled\" ) == null;\n} ) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\t\tnull;\n\t\t}\n\t} );\n}\n\nreturn Sizzle;\n\n} )( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n}\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( elem.contentDocument != null &&\n\n\t\t\t// Support: IE 11+\n\t\t\t// <object> elements with no `data` attribute has an object\n\t\t\t// `contentDocument` with a `null` prototype.\n\t\t\tgetProto( elem.contentDocument ) ) {\n\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( _i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the primary Deferred\n\t\t\tprimary = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tprimary.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( primary.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn primary.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );\n\t\t}\n\n\t\treturn primary.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, _key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\t\tvalue :\n\t\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( _all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// Support: IE <=9 only\n\t// IE <=9 replaces <option> tags with their contents when inserted outside of\n\t// the select element.\n\tdiv.innerHTML = \"<option></option>\";\n\tsupport.option = !!div.lastChild;\n} )();\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: IE <=9 only\nif ( !support.option ) {\n\twrapMap.optgroup = wrapMap.option = [ 1, \"<select multiple='multiple'>\", \"</select>\" ];\n}\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\nvar rtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Only attach events to objects that accept data\n\t\tif ( !acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = Object.create( null );\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\n\t\t\t// Make a writable jQuery.Event from the native event object\n\t\t\tevent = jQuery.event.fix( nativeEvent ),\n\n\t\t\thandlers = (\n\t\t\t\tdataPriv.get( this, \"events\" ) || Object.create( null )\n\t\t\t)[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\t\t// Support: Chrome 86+\n\t\t\t\t\t\t// In Chrome, if an element having a focusout handler is blurred by\n\t\t\t\t\t\t// clicking outside of it, it invokes the handler synchronously. If\n\t\t\t\t\t\t// that handler calls `.remove()` on the element, the data is cleared,\n\t\t\t\t\t\t// leaving `result` undefined. We need to guard against this.\n\t\t\t\t\t\treturn result && result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\twhich: true\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\t// Suppress native focus or blur as it's already being fired\n\t\t// in leverageNative.\n\t\t_default: function() {\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.get( src );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdataPriv.remove( dest, \"handle events\" );\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = flat( args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t}, doc );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html;\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.call( elem );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableTrDimensionsVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t},\n\n\t\t// Support: IE 9 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Behavior in IE 9 is more subtle than in newer versions & it passes\n\t\t// some versions of this test; make sure not to make it pass there!\n\t\t//\n\t\t// Support: Firefox 70+\n\t\t// Only Firefox includes border widths\n\t\t// in computed dimensions. (gh-4529)\n\t\treliableTrDimensions: function() {\n\t\t\tvar table, tr, trChild, trStyle;\n\t\t\tif ( reliableTrDimensionsVal == null ) {\n\t\t\t\ttable = document.createElement( \"table\" );\n\t\t\t\ttr = document.createElement( \"tr\" );\n\t\t\t\ttrChild = document.createElement( \"div\" );\n\n\t\t\t\ttable.style.cssText = \"position:absolute;left:-11111px;border-collapse:separate\";\n\t\t\t\ttr.style.cssText = \"border:1px solid\";\n\n\t\t\t\t// Support: Chrome 86+\n\t\t\t\t// Height set through cssText does not get applied.\n\t\t\t\t// Computed height then comes back as 0.\n\t\t\t\ttr.style.height = \"1px\";\n\t\t\t\ttrChild.style.height = \"9px\";\n\n\t\t\t\t// Support: Android 8 Chrome 86+\n\t\t\t\t// In our bodyBackground.html iframe,\n\t\t\t\t// display for all div elements is set to \"inline\",\n\t\t\t\t// which causes a problem only in Android 8 Chrome 86.\n\t\t\t\t// Ensuring the div is display: block\n\t\t\t\t// gets around this issue.\n\t\t\t\ttrChild.style.display = \"block\";\n\n\t\t\t\tdocumentElement\n\t\t\t\t\t.appendChild( table )\n\t\t\t\t\t.appendChild( tr )\n\t\t\t\t\t.appendChild( trChild );\n\n\t\t\t\ttrStyle = window.getComputedStyle( tr );\n\t\t\t\treliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderTopWidth, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;\n\n\t\t\t\tdocumentElement.removeChild( table );\n\t\t\t}\n\t\t\treturn reliableTrDimensionsVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( _elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Support: IE 9 - 11 only\n\t// Use offsetWidth/offsetHeight for when box sizing is unreliable.\n\t// In those cases, the computed value can be trusted to be border-box.\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\n\t\t// Support: IE 10 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Interestingly, in some cases IE 9 doesn't suffer from this issue.\n\t\t!support.reliableTrDimensions() && nodeName( elem, \"tr\" ) ||\n\n\t\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t\t// This happens for inline elements with no explicit setting (gh-3571)\n\t\tval === \"auto\" ||\n\n\t\t// Support: Android <=4.1 - 4.3 only\n\t\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\n\t\t// Make sure the element is visible & connected\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( _i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t} ) :\n\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\n\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( _i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( _i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || Object.create( null ) )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\n\t\t\t\t// Handle: regular nodes (via `this.ownerDocument`), window\n\t\t\t\t// (via `this.document`) & document (via `this`).\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = { guid: Date.now() };\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, parserErrorElem;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {}\n\n\tparserErrorElem = xml && xml.getElementsByTagName( \"parsererror\" )[ 0 ];\n\tif ( !xml || parserErrorElem ) {\n\t\tjQuery.error( \"Invalid XML: \" + (\n\t\t\tparserErrorElem ?\n\t\t\t\tjQuery.map( parserErrorElem.childNodes, function( el ) {\n\t\t\t\t\treturn el.textContent;\n\t\t\t\t} ).join( \"\\n\" ) :\n\t\t\t\tdata\n\t\t) );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} ).filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} ).map( function( _i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\noriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce.guid++ ) +\n\t\t\t\t\tuncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Use a noop converter for missing script but not if jsonp\n\t\t\tif ( !isSuccess &&\n\t\t\t\tjQuery.inArray( \"script\", s.dataTypes ) > -1 &&\n\t\t\t\tjQuery.inArray( \"json\", s.dataTypes ) < 0 ) {\n\t\t\t\ts.converters[ \"text script\" ] = function() {};\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( _i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\njQuery.ajaxPrefilter( function( s ) {\n\tvar i;\n\tfor ( i in s.headers ) {\n\t\tif ( i.toLowerCase() === \"content-type\" ) {\n\t\t\ts.contentType = s.headers[ i ] || \"\";\n\t\t}\n\t}\n} );\n\n\njQuery._evalUrl = function( url, options, doc ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options, doc );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( \"load error\", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce.guid++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( _i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( {\n\t\tpadding: \"inner\" + name,\n\t\tcontent: type,\n\t\t\"\": \"outer\" + name\n\t}, function( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( _i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\njQuery.each(\n\t( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( _i, name ) {\n\n\t\t// Handle event binding\n\t\tjQuery.fn[ name ] = function( data, fn ) {\n\t\t\treturn arguments.length > 0 ?\n\t\t\t\tthis.on( name, null, data, fn ) :\n\t\t\t\tthis.trigger( name );\n\t\t};\n\t}\n);\n\n\n\n\n// Support: Android <=4.0 only\n// Make sure we trim BOM and NBSP\nvar rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\njQuery.trim = function( text ) {\n\treturn text == null ?\n\t\t\"\" :\n\t\t( text + \"\" ).replace( rtrim, \"\" );\n};\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === \"undefined\" ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "docs/_static/jquery.js",
    "content": "/*! jQuery v3.1.0 | (c) jQuery Foundation | jquery.org/license */\n!function(a,b){\"use strict\";\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error(\"jQuery requires a window with a document\");return b(a)}:b(a)}(\"undefined\"!=typeof window?window:this,function(a,b){\"use strict\";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement(\"script\");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q=\"3.1.0\",r=function(a,b){return new r.fn.init(a,b)},s=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?a<0?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for(\"boolean\"==typeof g&&(j=g,g=arguments[h]||{},h++),\"object\"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:\"jQuery\"+(q+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return\"function\"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return(\"number\"===b||\"string\"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||\"[object Object]\"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,\"constructor\")&&b.constructor,\"function\"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+\"\":\"object\"==typeof a||\"function\"==typeof a?j[k.call(a)]||\"object\":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,\"ms-\").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?\"\":(a+\"\").replace(s,\"\")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,\"string\"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if(\"string\"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),\"function\"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(a,b){j[\"[object \"+b+\"]\"]=b.toLowerCase()});function w(a){var b=!!a&&\"length\"in a&&a.length,c=r.type(a);return\"function\"!==c&&!r.isWindow(a)&&(\"array\"===c||0===b||\"number\"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u=\"sizzle\"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",K=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",L=\"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",M=\"\\\\[\"+K+\"*(\"+L+\")(?:\"+K+\"*([*^$|!~]?=)\"+K+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+L+\"))|)\"+K+\"*\\\\]\",N=\":(\"+L+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+M+\")*)|.*)\\\\)|)\",O=new RegExp(K+\"+\",\"g\"),P=new RegExp(\"^\"+K+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+K+\"+$\",\"g\"),Q=new RegExp(\"^\"+K+\"*,\"+K+\"*\"),R=new RegExp(\"^\"+K+\"*([>+~]|\"+K+\")\"+K+\"*\"),S=new RegExp(\"=\"+K+\"*([^\\\\]'\\\"]*?)\"+K+\"*\\\\]\",\"g\"),T=new RegExp(N),U=new RegExp(\"^\"+L+\"$\"),V={ID:new RegExp(\"^#(\"+L+\")\"),CLASS:new RegExp(\"^\\\\.(\"+L+\")\"),TAG:new RegExp(\"^(\"+L+\"|[*])\"),ATTR:new RegExp(\"^\"+M),PSEUDO:new RegExp(\"^\"+N),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+K+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+K+\"*(?:([+-]|)\"+K+\"*(\\\\d+)|))\"+K+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+J+\")$\",\"i\"),needsContext:new RegExp(\"^\"+K+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+K+\"*((?:-\\\\d)?\\\\d*)\"+K+\"*\\\\)|)(?=[^-]|$)\",\"i\")},W=/^(?:input|select|textarea|button)$/i,X=/^h\\d$/i,Y=/^[^{]+\\{\\s*\\[native \\w/,Z=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,$=/[+~]/,_=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+K+\"?|(\"+K+\")|.)\",\"ig\"),aa=function(a,b,c){var d=\"0x\"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\x80-\\uFFFF\\w-]/g,ca=function(a,b){return b?\"\\0\"===a?\"\\ufffd\":a.slice(0,-1)+\"\\\\\"+a.charCodeAt(a.length-1).toString(16)+\" \":\"\\\\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:\"parentNode\",next:\"legend\"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],\"string\"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+\" \"]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if(\"object\"!==b.nodeName.toLowerCase()){(k=b.getAttribute(\"id\"))?k=k.replace(ba,ca):b.setAttribute(\"id\",k=u),o=g(a),h=o.length;while(h--)o[h]=\"#\"+k+\" \"+sa(o[h]);r=o.join(\",\"),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute(\"id\")}}}return i(a.replace(P,\"$1\"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+\" \")>d.cacheLength&&delete b[a.shift()],b[c+\" \"]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement(\"fieldset\");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split(\"|\"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return\"input\"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return(\"input\"===c||\"button\"===c)&&b.type===a}}function oa(a){return function(b){return\"label\"in b&&b.disabled===a||\"form\"in b&&b.disabled===a||\"form\"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&(\"label\"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&\"undefined\"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&\"HTML\"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener(\"unload\",da,!1):e.attachEvent&&e.attachEvent(\"onunload\",da)),c.attributes=ja(function(a){return a.className=\"i\",!a.getAttribute(\"className\")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment(\"\")),!a.getElementsByTagName(\"*\").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(\"undefined\"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute(\"id\")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c=\"undefined\"!=typeof a.getAttributeNode&&a.getAttributeNode(\"id\");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return\"undefined\"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if(\"*\"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if(\"undefined\"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML=\"<a id='\"+u+\"'></a><select id='\"+u+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",a.querySelectorAll(\"[msallowcapture^='']\").length&&q.push(\"[*^$]=\"+K+\"*(?:''|\\\"\\\")\"),a.querySelectorAll(\"[selected]\").length||q.push(\"\\\\[\"+K+\"*(?:value|\"+J+\")\"),a.querySelectorAll(\"[id~=\"+u+\"-]\").length||q.push(\"~=\"),a.querySelectorAll(\":checked\").length||q.push(\":checked\"),a.querySelectorAll(\"a#\"+u+\"+*\").length||q.push(\".#.+[+~]\")}),ja(function(a){a.innerHTML=\"<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>\";var b=n.createElement(\"input\");b.setAttribute(\"type\",\"hidden\"),a.appendChild(b).setAttribute(\"name\",\"D\"),a.querySelectorAll(\"[name=d]\").length&&q.push(\"name\"+K+\"*[*^$|!~]?=\"),2!==a.querySelectorAll(\":enabled\").length&&q.push(\":enabled\",\":disabled\"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(\":disabled\").length&&q.push(\":enabled\",\":disabled\"),a.querySelectorAll(\"*,:x\"),q.push(\",.*:\")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,\"*\"),s.call(a,\"[s!='']:x\"),r.push(\"!=\",N)}),q=q.length&&new RegExp(q.join(\"|\")),r=r.length&&new RegExp(r.join(\"|\")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,\"='$1']\"),c.matchesSelector&&p&&!A[b+\" \"]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+\"\").replace(ba,ca)},ga.error=function(a){throw new Error(\"Syntax error, unrecognized expression: \"+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c=\"\",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if(\"string\"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||\"\").replace(_,aa),\"~=\"===a[2]&&(a[3]=\" \"+a[3]+\" \"),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),\"nth\"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*(\"even\"===a[3]||\"odd\"===a[3])),a[5]=+(a[7]+a[8]||\"odd\"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||\"\":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(\")\",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return\"*\"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+\" \"];return b||(b=new RegExp(\"(^|\"+K+\")\"+a+\"(\"+K+\"|$)\"))&&y(a,function(a){return b.test(\"string\"==typeof a.className&&a.className||\"undefined\"!=typeof a.getAttribute&&a.getAttribute(\"class\")||\"\")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?\"!=\"===b:!b||(e+=\"\",\"=\"===b?e===c:\"!=\"===b?e!==c:\"^=\"===b?c&&0===e.indexOf(c):\"*=\"===b?c&&e.indexOf(c)>-1:\"$=\"===b?c&&e.slice(-c.length)===c:\"~=\"===b?(\" \"+e.replace(O,\" \")+\" \").indexOf(c)>-1:\"|=\"===b&&(e===c||e.slice(0,c.length+1)===c+\"-\"))}},CHILD:function(a,b,c,d,e){var f=\"nth\"!==a.slice(0,3),g=\"last\"!==a.slice(-4),h=\"of-type\"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?\"nextSibling\":\"previousSibling\",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p=\"only\"===a&&!o&&\"nextSibling\"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error(\"unsupported pseudo: \"+a);return e[u]?e(b):e.length>1?(c=[a,a,\"\",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,\"$1\"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||\"\")||ga.error(\"unsupported lang: \"+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute(\"xml:lang\")||b.getAttribute(\"lang\"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+\"-\");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&!!a.checked||\"option\"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&\"button\"===a.type||\"button\"===b},text:function(a){var b;return\"input\"===a.nodeName.toLowerCase()&&\"text\"===a.type&&(null==(b=a.getAttribute(\"type\"))||\"text\"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+\" \"];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P,\" \")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d=\"\";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&\"parentNode\"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e)}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||\"*\",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[\" \"],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:\" \"===a[i-2].type?\"*\":\"\"})).replace(P,\"$1\"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s=\"0\",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG(\"*\",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+\" \"];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n=\"function\"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&\"ID\"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split(\"\").sort(B).join(\"\")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement(\"fieldset\"))}),ja(function(a){return a.innerHTML=\"<a href='#'></a>\",\"#\"===a.firstChild.getAttribute(\"href\")})||ka(\"type|href|height|width\",function(a,b,c){if(!c)return a.getAttribute(b,\"type\"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML=\"<input/>\",a.firstChild.setAttribute(\"value\",\"\"),\"\"===a.firstChild.getAttribute(\"value\")})||ka(\"value\",function(a,b,c){if(!c&&\"input\"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute(\"disabled\")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[\":\"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i,C=/^.[^:#\\[\\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if(\"string\"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=\":not(\"+a+\")\"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if(\"string\"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,\"string\"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,\"string\"==typeof a){if(e=\"<\"===a[0]&&\">\"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g=\"string\"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?\"string\"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,\"parentNode\")},parentsUntil:function(a,b,c){return y(a,\"parentNode\",c)},next:function(a){return J(a,\"nextSibling\")},prev:function(a){return J(a,\"previousSibling\")},nextAll:function(a){return y(a,\"nextSibling\")},prevAll:function(a){return y(a,\"previousSibling\")},nextUntil:function(a,b,c){return y(a,\"nextSibling\",c)},prevUntil:function(a,b,c){return y(a,\"previousSibling\",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return\"Until\"!==a.slice(-5)&&(d=c),d&&\"string\"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a=\"string\"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:\"\")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&\"string\"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c=\"\",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=\"\"),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[[\"notify\",\"progress\",r.Callbacks(\"memory\"),r.Callbacks(\"memory\"),2],[\"resolve\",\"done\",r.Callbacks(\"once memory\"),r.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",r.Callbacks(\"once memory\"),r.Callbacks(\"once memory\"),1,\"rejected\"]],d=\"pending\",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},\"catch\":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+\"With\"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError(\"Thenable self-resolution\");j=a&&(\"object\"==typeof a||\"function\"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+\"With\"](this===f?void 0:this,arguments),this},f[b[0]+\"With\"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),\"pending\"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn(\"jQuery.Deferred exception: \"+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)[\"catch\"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener(\"DOMContentLoaded\",R),a.removeEventListener(\"load\",R),r.ready()}\"complete\"===d.readyState||\"loading\"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener(\"DOMContentLoaded\",R),a.addEventListener(\"load\",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if(\"object\"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,\nr.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if(\"string\"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&\"string\"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,Y=/[A-Z]/g;function Z(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d=\"data-\"+b.replace(Y,\"-$&\").toLowerCase(),c=a.getAttribute(d),\"string\"==typeof c){try{c=\"true\"===c||\"false\"!==c&&(\"null\"===c?null:+c+\"\"===c?+c:X.test(c)?JSON.parse(c):c)}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,\"hasDataAttrs\"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf(\"data-\")&&(d=r.camelCase(d.slice(5)),Z(f,d,e[d])));V.set(f,\"hasDataAttrs\",!0)}return e}return\"object\"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=Z(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||\"fx\")+\"queue\",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||\"fx\";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};\"inprogress\"===e&&(e=c.shift(),d--),e&&(\"fx\"===b&&c.unshift(\"inprogress\"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+\"queueHooks\";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks(\"once memory\").add(function(){V.remove(a,[b+\"queue\",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return\"string\"!=typeof a&&(b=a,a=\"fx\",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),\"fx\"===a&&\"inprogress\"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||\"fx\",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};\"string\"!=typeof a&&(b=a,a=void 0),a=a||\"fx\";while(g--)c=V.get(f[g],a+\"queueHooks\"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var $=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,_=new RegExp(\"^(?:([+-])=|)(\"+$+\")([a-z%]*)$\",\"i\"),aa=[\"Top\",\"Right\",\"Bottom\",\"Left\"],ba=function(a,b){return a=b||a,\"none\"===a.style.display||\"\"===a.style.display&&r.contains(a.ownerDocument,a)&&\"none\"===r.css(a,\"display\")},ca=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function da(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,\"\")},i=h(),j=c&&c[3]||(r.cssNumber[b]?\"\":\"px\"),k=(r.cssNumber[b]||\"px\"!==j&&+i)&&_.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||\".5\",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ea={};function fa(a){var b,c=a.ownerDocument,d=a.nodeName,e=ea[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,\"display\"),b.parentNode.removeChild(b),\"none\"===e&&(e=\"block\"),ea[d]=e,e)}function ga(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?(\"none\"===c&&(e[f]=V.get(d,\"display\")||null,e[f]||(d.style.display=\"\")),\"\"===d.style.display&&ba(d)&&(e[f]=fa(d))):\"none\"!==c&&(e[f]=\"none\",V.set(d,\"display\",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ga(this,!0)},hide:function(){return ga(this)},toggle:function(a){return\"boolean\"==typeof a?a?this.show():this.hide():this.each(function(){ba(this)?r(this).show():r(this).hide()})}});var ha=/^(?:checkbox|radio)$/i,ia=/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i,ja=/^$|\\/(?:java|ecma)script/i,ka={option:[1,\"<select multiple='multiple'>\",\"</select>\"],thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c=\"undefined\"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||\"*\"):\"undefined\"!=typeof a.querySelectorAll?a.querySelectorAll(b||\"*\"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;c<d;c++)V.set(a[c],\"globalEval\",!b||V.get(b[c],\"globalEval\"))}var na=/<|&#?\\w+;/;function oa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if(\"object\"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(na.test(f)){g=g||l.appendChild(b.createElement(\"div\")),h=(ia.exec(f)||[\"\",\"\"])[1].toLowerCase(),i=ka[h]||ka._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=\"\"}else m.push(b.createTextNode(f));l.textContent=\"\",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),\"script\"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||\"\")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement(\"div\")),c=d.createElement(\"input\");c.setAttribute(\"type\",\"radio\"),c.setAttribute(\"checked\",\"checked\"),c.setAttribute(\"name\",\"t\"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML=\"<textarea>x</textarea>\",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if(\"object\"==typeof b){\"string\"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&(\"string\"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return\"undefined\"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||\"\").match(K)||[\"\"],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||\"\").split(\".\").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(\".\")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||\"\").match(K)||[\"\"],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||\"\").split(\".\").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp(\"(^|\\\\.)\"+o.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&(\"**\"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,\"handle events\")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,\"events\")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(\"click\"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||\"click\"!==a.type)){for(d=[],c=0;c<h;c++)f=b[c],e=f.selector+\" \",void 0===d[e]&&(d[e]=f.needsContext?r(e,this).index(i)>-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==va()&&this.focus)return this.focus(),!1},delegateType:\"focusin\"},blur:{trigger:function(){if(this===va()&&this.blur)return this.blur(),!1},delegateType:\"focusout\"},click:{trigger:function(){if(\"checkbox\"===this.type&&this.click&&r.nodeName(this,\"input\"))return this.click(),!1},_default:function(a){return r.nodeName(a.target,\"a\")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ta:ua,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:ua,isPropagationStopped:ua,isImmediatePropagationStopped:ua,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ta,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ta,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ta,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,\"char\":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&qa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ra.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return wa(this,a,b,c,d)},one:function(a,b,c,d){return wa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+\".\"+d.namespace:d.origType,d.selector,d.handler),this;if(\"object\"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&\"function\"!=typeof b||(c=b,b=void 0),c===!1&&(c=ua),this.each(function(){r.event.remove(this,a,c,b)})}});var xa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,ya=/<script|<style|<link/i,za=/checked\\s*(?:[^=]|=\\s*.checked.)/i,Aa=/^true\\/(.*)/,Ba=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;function Ca(a,b){return r.nodeName(a,\"table\")&&r.nodeName(11!==b.nodeType?b:b.firstChild,\"tr\")?a.getElementsByTagName(\"tbody\")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute(\"type\"))+\"/\"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute(\"type\"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ga(a,b){var c=b.nodeName.toLowerCase();\"input\"===c&&ha.test(a.type)?b.checked=a.checked:\"input\"!==c&&\"textarea\"!==c||(b.defaultValue=a.defaultValue)}function Ha(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&\"string\"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,\"script\"),Da),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,la(j,\"script\"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ea),l=0;l<i;l++)j=h[l],ja.test(j.type||\"\")&&!V.access(j,\"globalEval\")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ba,\"\"),k))}return a}function Ia(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(la(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&ma(la(d,\"script\")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(xa,\"<$1></$2>\")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;d<e;d++)Ga(f[d],g[d]);if(b)if(c)for(f=f||la(a),g=g||la(h),d=0,e=f.length;d<e;d++)Fa(f[d],g[d]);else Fa(a,h);return g=la(h,\"script\"),g.length>0&&ma(g,!i&&la(a,\"script\")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(a,!1)),a.textContent=\"\");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if(\"string\"==typeof a&&!ya.test(a)&&!ka[(ia.exec(a)||[\"\",\"\"])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(la(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(la(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ja=/^margin/,Ka=new RegExp(\"^(\"+$+\")(?!px)[a-z%]+$\",\"i\"),La=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText=\"box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",i.innerHTML=\"\",pa.appendChild(h);var b=a.getComputedStyle(i);c=\"1%\"!==b.top,g=\"2px\"===b.marginLeft,e=\"4px\"===b.width,i.style.marginRight=\"50%\",f=\"4px\"===b.marginRight,pa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement(\"div\"),i=d.createElement(\"div\");i.style&&(i.style.backgroundClip=\"content-box\",i.cloneNode(!0).style.backgroundClip=\"\",o.clearCloneStyle=\"content-box\"===i.style.backgroundClip,h.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Ma(a,b,c){var d,e,f,g,h=a.style;return c=c||La(a),c&&(g=c.getPropertyValue(b)||c[b],\"\"!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ka.test(g)&&Ja.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+\"\":g}function Na(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Oa=/^(none|table(?!-c[ea]).+)/,Pa={position:\"absolute\",visibility:\"hidden\",display:\"block\"},Qa={letterSpacing:\"0\",fontWeight:\"400\"},Ra=[\"Webkit\",\"Moz\",\"ms\"],Sa=d.createElement(\"div\").style;function Ta(a){if(a in Sa)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ra.length;while(c--)if(a=Ra[c]+b,a in Sa)return a}function Ua(a,b,c){var d=_.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||\"px\"):b}function Va(a,b,c,d,e){for(var f=c===(d?\"border\":\"content\")?4:\"width\"===b?1:0,g=0;f<4;f+=2)\"margin\"===c&&(g+=r.css(a,c+aa[f],!0,e)),d?(\"content\"===c&&(g-=r.css(a,\"padding\"+aa[f],!0,e)),\"margin\"!==c&&(g-=r.css(a,\"border\"+aa[f]+\"Width\",!0,e))):(g+=r.css(a,\"padding\"+aa[f],!0,e),\"padding\"!==c&&(g+=r.css(a,\"border\"+aa[f]+\"Width\",!0,e)));return g}function Wa(a,b,c){var d,e=!0,f=La(a),g=\"border-box\"===r.css(a,\"boxSizing\",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),d<=0||null==d){if(d=Ma(a,b,f),(d<0||null==d)&&(d=a.style[b]),Ka.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Va(a,b,c||(g?\"border\":\"content\"),e,f)+\"px\"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ma(a,\"opacity\");return\"\"===c?\"1\":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":\"cssFloat\"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&\"get\"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,\"string\"===f&&(e=_.exec(c))&&e[1]&&(c=da(a,b,e),f=\"number\"),null!=c&&c===c&&(\"number\"===f&&(c+=e&&e[3]||(r.cssNumber[h]?\"\":\"px\")),o.clearCloneStyle||\"\"!==c||0!==b.indexOf(\"background\")||(i[b]=\"inherit\"),g&&\"set\"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&\"get\"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Ma(a,b,d)),\"normal\"===e&&b in Qa&&(e=Qa[b]),\"\"===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each([\"height\",\"width\"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Oa.test(r.css(a,\"display\"))||a.getClientRects().length&&a.getBoundingClientRect().width?Wa(a,b,d):ca(a,Pa,function(){return Wa(a,b,d)})},set:function(a,c,d){var e,f=d&&La(a),g=d&&Va(a,b,d,\"border-box\"===r.css(a,\"boxSizing\",!1,f),f);return g&&(e=_.exec(c))&&\"px\"!==(e[3]||\"px\")&&(a.style[b]=c,c=r.css(a,b)),Ua(a,c,g)}}}),r.cssHooks.marginLeft=Na(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Ma(a,\"marginLeft\"))||a.getBoundingClientRect().left-ca(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+\"px\"}),r.each({margin:\"\",padding:\"\",border:\"Width\"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f=\"string\"==typeof c?c.split(\" \"):[c];d<4;d++)e[a+aa[d]+b]=f[d]||f[d-2]||f[0];return e}},Ja.test(a)||(r.cssHooks[a+b].set=Ua)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=La(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?\"\":\"px\")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,\"\"),b&&\"auto\"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:\"swing\"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=aa[d],e[\"margin\"+c]=e[\"padding\"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners[\"*\"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function eb(a,b,c){var d,e,f,g,h,i,j,k,l=\"width\"in b||\"height\"in b,m=this,n={},o=a.style,p=a.nodeType&&ba(a),q=V.get(a,\"fxshow\");c.queue||(g=r._queueHooks(a,\"fx\"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,\"fx\").length||g.empty.fire()})}));for(d in b)if(e=b[d],$a.test(e)){if(delete b[d],f=f||\"toggle\"===e,e===(p?\"hide\":\"show\")){if(\"show\"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,\"display\")),k=r.css(a,\"display\"),\"none\"===k&&(j?k=j:(ga([a],!0),j=a.style.display||j,k=r.css(a,\"display\"),ga([a]))),(\"inline\"===k||\"inline-block\"===k&&null!=j)&&\"none\"===r.css(a,\"float\")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j=\"none\"===k?\"\":k)),o.display=\"inline-block\")),c.overflow&&(o.overflow=\"hidden\",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?\"hidden\"in q&&(p=q.hidden):q=V.access(a,\"fxshow\",{display:j}),f&&(q.hidden=!p),p&&ga([a],!0),m.done(function(){p||ga([a]),V.remove(a,\"fxshow\");for(d in n)r.style(a,d,n[d])})),i=db(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function fb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&\"expand\"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function gb(a,b,c){var d,e,f=0,g=gb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Ya||bb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Ya||bb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(fb(k,j.opts.specialEasing);f<g;f++)if(d=gb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,db,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(gb,{tweeners:{\"*\":[function(a,b){var c=this.createTween(a,b);return da(c.elem,a,_.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=[\"*\"]):a=a.match(K);for(var c,d=0,e=a.length;d<e;d++)c=a[d],gb.tweeners[c]=gb.tweeners[c]||[],gb.tweeners[c].unshift(b)},prefilters:[eb],prefilter:function(a,b){b?gb.prefilters.unshift(a):gb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&\"object\"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:e.duration=\"number\"==typeof e.duration?e.duration:e.duration in r.fx.speeds?r.fx.speeds[e.duration]:r.fx.speeds._default,null!=e.queue&&e.queue!==!0||(e.queue=\"fx\"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ba).css(\"opacity\",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=gb(this,r.extend({},a),f);(e||V.get(this,\"finish\"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return\"string\"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||\"fx\",[]),this.each(function(){var b=!0,e=null!=a&&a+\"queueHooks\",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&_a.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||\"fx\"),this.each(function(){var b,c=V.get(this),d=c[a+\"queue\"],e=c[a+\"queueHooks\"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each([\"toggle\",\"show\",\"hide\"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||\"boolean\"==typeof a?c.apply(this,arguments):this.animate(cb(b,!0),a,d,e)}}),r.each({slideDown:cb(\"show\"),slideUp:cb(\"hide\"),slideToggle:cb(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Ya=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),Ya=void 0},r.fx.timer=function(a){r.timers.push(a),a()?r.fx.start():r.timers.pop()},r.fx.interval=13,r.fx.start=function(){Za||(Za=a.requestAnimationFrame?a.requestAnimationFrame(ab):a.setInterval(r.fx.tick,r.fx.interval))},r.fx.stop=function(){a.cancelAnimationFrame?a.cancelAnimationFrame(Za):a.clearInterval(Za),Za=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||\"fx\",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement(\"input\"),b=d.createElement(\"select\"),c=b.appendChild(d.createElement(\"option\"));a.type=\"checkbox\",o.checkOn=\"\"!==a.value,o.optSelected=c.selected,a=d.createElement(\"input\"),a.value=\"t\",a.type=\"radio\",o.radioValue=\"t\"===a.value}();var hb,ib=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return S(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return\"undefined\"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+\"\"),c):e&&\"get\"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&\"radio\"===b&&r.nodeName(a,\"input\")){var c=a.value;return a.setAttribute(\"type\",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);\nif(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&\"get\"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,\"tabindex\");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\\t\\r\\n\\f]/g;function mb(a){return a.getAttribute&&a.getAttribute(\"class\")||\"\"}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if(\"string\"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(\" \"+e+\" \").replace(lb,\" \")){g=0;while(f=b[g++])d.indexOf(\" \"+f+\" \")<0&&(d+=f+\" \");h=r.trim(d),e!==h&&c.setAttribute(\"class\",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(\" \"+e+\" \").replace(lb,\" \")){g=0;while(f=b[g++])while(d.indexOf(\" \"+f+\" \")>-1)d=d.replace(\" \"+f+\" \",\" \");h=r.trim(d),e!==h&&c.setAttribute(\"class\",h)}}return this},toggleClass:function(a,b){var c=typeof a;return\"boolean\"==typeof b&&\"string\"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if(\"string\"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&\"boolean\"!==c||(b=mb(this),b&&V.set(this,\"__className__\",b),this.setAttribute&&this.setAttribute(\"class\",b||a===!1?\"\":V.get(this,\"__className__\")||\"\"))})},hasClass:function(a){var b,c,d=0;b=\" \"+a+\" \";while(c=this[d++])if(1===c.nodeType&&(\" \"+mb(c)+\" \").replace(lb,\" \").indexOf(b)>-1)return!0;return!1}});var nb=/\\r/g,ob=/[\\x20\\t\\r\\n\\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e=\"\":\"number\"==typeof e?e+=\"\":r.isArray(e)&&(e=r.map(e,function(a){return null==a?\"\":a+\"\"})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&\"set\"in b&&void 0!==b.set(this,e,\"value\")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&\"get\"in b&&void 0!==(c=b.get(e,\"value\"))?c:(c=e.value,\"string\"==typeof c?c.replace(nb,\"\"):null==c?\"\":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,\"value\");return null!=b?b:r.trim(r.text(a)).replace(ob,\" \")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f=\"select-one\"===a.type,g=f?null:[],h=f?e+1:d.length,i=e<0?h:f?e:0;i<h;i++)if(c=d[i],(c.selected||i===e)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,\"optgroup\"))){if(b=r(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each([\"radio\",\"checkbox\"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute(\"value\")?\"on\":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,\"type\")?b.type:b,q=l.call(b,\"namespace\")?b.namespace.split(\".\"):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(\".\")>-1&&(q=p.split(\".\"),p=q.shift(),q.sort()),k=p.indexOf(\":\")<0&&\"on\"+p,b=b[r.expando]?b:new r.Event(p,\"object\"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join(\".\"),b.rnamespace=b.namespace?new RegExp(\"(^|\\\\.)\"+q.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,\"events\")||{})[b.type]&&V.get(h,\"handle\"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin=\"onfocusin\"in a,o.focusin||r.each({focus:\"focusin\",blur:\"focusout\"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\\?/;r.parseXML=function(b){var c;if(!b||\"string\"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,\"text/xml\")}catch(d){c=void 0}return c&&!c.getElementsByTagName(\"parsererror\").length||r.error(\"Invalid XML: \"+b),c};var tb=/\\[\\]$/,ub=/\\r?\\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+\"[\"+(\"object\"==typeof e&&null!=e?b:\"\")+\"]\",e,c,d)});else if(c||\"object\"!==r.type(b))d(a,b);else for(e in b)xb(a+\"[\"+e+\"]\",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+\"=\"+encodeURIComponent(null==c?\"\":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join(\"&\")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,\"elements\");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(\":disabled\")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,\"\\r\\n\")}}):{name:b.name,value:c.replace(ub,\"\\r\\n\")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\\/\\//,Fb={},Gb={},Hb=\"*/\".concat(\"*\"),Ib=d.createElement(\"a\");Ib.href=qb.href;function Jb(a){return function(b,c){\"string\"!=typeof b&&(c=b,b=\"*\");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])\"+\"===d[0]?(d=d.slice(1)||\"*\",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return\"string\"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e[\"*\"]&&g(\"*\")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while(\"*\"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader(\"Content-Type\"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+\" \"+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if(\"*\"===f)f=i;else if(\"*\"!==i&&i!==f){if(g=j[i+\" \"+f]||j[\"* \"+f],!g)for(e in j)if(h=e.split(\" \"),h[1]===f&&(g=j[i+\" \"+h[0]]||j[\"* \"+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a[\"throws\"])b=g(b);else try{b=g(b)}catch(l){return{state:\"parsererror\",error:g?l:\"No conversion from \"+i+\" to \"+f}}}return{state:\"success\",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:\"GET\",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Hb,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){\"object\"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks(\"once memory\"),u=o.statusCode||{},v={},w={},x=\"canceled\",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+\"\").replace(Eb,qb.protocol+\"//\"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||\"*\").toLowerCase().match(K)||[\"\"],null==o.crossDomain){j=d.createElement(\"a\");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+\"//\"+Ib.host!=j.protocol+\"//\"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&\"string\"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger(\"ajaxStart\"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,\"\"),o.hasContent?o.data&&o.processData&&0===(o.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(o.data=o.data.replace(yb,\"+\")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?\"&\":\"?\")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,\"\"),n=(sb.test(f)?\"&\":\"?\")+\"_=\"+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader(\"If-Modified-Since\",r.lastModified[f]),r.etag[f]&&y.setRequestHeader(\"If-None-Match\",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader(\"Content-Type\",o.contentType),y.setRequestHeader(\"Accept\",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+(\"*\"!==o.dataTypes[0]?\", \"+Hb+\"; q=0.01\":\"\"):o.accepts[\"*\"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x=\"abort\",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger(\"ajaxSend\",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort(\"timeout\")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,\"No Transport\");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||\"\",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader(\"Last-Modified\"),w&&(r.lastModified[f]=w),w=y.getResponseHeader(\"etag\"),w&&(r.etag[f]=w)),204===b||\"HEAD\"===o.type?x=\"nocontent\":304===b?x=\"notmodified\":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x=\"error\",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+\"\",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?\"ajaxSuccess\":\"ajaxError\",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger(\"ajaxComplete\",[y,o]),--r.active||r.event.trigger(\"ajaxStop\")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,\"json\")},getScript:function(a,b){return r.get(a,void 0,b,\"script\")}}),r.each([\"get\",\"post\"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,\"throws\":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not(\"body\").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&\"withCredentials\"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e[\"X-Requested-With\"]||(e[\"X-Requested-With\"]=\"XMLHttpRequest\");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,\"abort\"===a?h.abort():\"error\"===a?\"number\"!=typeof h.status?f(0,\"error\"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,\"text\"!==(h.responseType||\"text\")||\"string\"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c(\"error\"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c(\"abort\");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter(\"script\",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type=\"GET\")}),r.ajaxTransport(\"script\",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(\"<script>\").prop({charset:a.scriptCharset,src:a.url}).on(\"load error\",c=function(a){b.remove(),c=null,a&&f(\"error\"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Qb=[],Rb=/(=)\\?(?=&|$)|\\?\\?/;r.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var a=Qb.pop()||r.expando+\"_\"+rb++;return this[a]=!0,a}}),r.ajaxPrefilter(\"json jsonp\",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Rb.test(b.url)?\"url\":\"string\"==typeof b.data&&0===(b.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Rb.test(b.data)&&\"data\");if(h||\"jsonp\"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Rb,\"$1\"+e):b.jsonp!==!1&&(b.url+=(sb.test(b.url)?\"&\":\"?\")+b.jsonp+\"=\"+e),b.converters[\"script json\"]=function(){return g||r.error(e+\" was not called\"),g[0]},b.dataTypes[0]=\"json\",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Qb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),\"script\"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument(\"\").body;return a.innerHTML=\"<form></form><form></form>\",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if(\"string\"!=typeof a)return[];\"boolean\"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(\"\"),e=b.createElement(\"base\"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=B.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=oa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(\" \");return h>-1&&(d=r.trim(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&\"object\"==typeof b&&(e=\"POST\"),g.length>0&&r.ajax({url:a,type:e||\"GET\",dataType:\"html\",data:b}).done(function(a){f=arguments,g.html(d?r(\"<div>\").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length};function Sb(a){return r.isWindow(a)?a:9===a.nodeType&&a.defaultView}r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,\"position\"),l=r(a),m={};\"static\"===k&&(a.style.position=\"relative\"),h=l.offset(),f=r.css(a,\"top\"),i=r.css(a,\"left\"),j=(\"absolute\"===k||\"fixed\"===k)&&(f+i).indexOf(\"auto\")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),\"using\"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),d.width||d.height?(e=f.ownerDocument,c=Sb(e),b=e.documentElement,{top:d.top+c.pageYOffset-b.clientTop,left:d.left+c.pageXOffset-b.clientLeft}):d):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return\"fixed\"===r.css(c,\"position\")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),r.nodeName(a[0],\"html\")||(d=a.offset()),d={top:d.top+r.css(a[0],\"borderTopWidth\",!0),left:d.left+r.css(a[0],\"borderLeftWidth\",!0)}),{top:b.top-d.top-r.css(c,\"marginTop\",!0),left:b.left-d.left-r.css(c,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&\"static\"===r.css(a,\"position\"))a=a.offsetParent;return a||pa})}}),r.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(a,b){var c=\"pageYOffset\"===b;r.fn[a]=function(d){return S(this,function(a,d,e){var f=Sb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each([\"top\",\"left\"],function(a,b){r.cssHooks[b]=Na(o.pixelPosition,function(a,c){if(c)return c=Ma(a,b),Ka.test(c)?r(a).position()[b]+\"px\":c})}),r.each({Height:\"height\",Width:\"width\"},function(a,b){r.each({padding:\"inner\"+a,content:b,\"\":\"outer\"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||\"boolean\"!=typeof e),h=c||(e===!0||f===!0?\"margin\":\"border\");return S(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf(\"outer\")?b[\"inner\"+a]:b.document.documentElement[\"client\"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body[\"scroll\"+a],f[\"scroll\"+a],b.body[\"offset\"+a],f[\"offset\"+a],f[\"client\"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,\"**\"):this.off(b,a||\"**\",c)}}),r.parseJSON=JSON.parse,\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return r});var Tb=a.jQuery,Ub=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Ub),b&&a.jQuery===r&&(a.jQuery=Tb),r},b||(a.jQuery=a.$=r),r});\n"
  },
  {
    "path": "docs/_static/js/theme.js",
    "content": "require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({\"sphinx-rtd-theme\":[function(require,module,exports){\nvar jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');\n\n// Sphinx theme nav state\nfunction ThemeNav () {\n\n    var nav = {\n        navBar: null,\n        win: null,\n        winScroll: false,\n        winResize: false,\n        linkScroll: false,\n        winPosition: 0,\n        winHeight: null,\n        docHeight: null,\n        isRunning: false\n    };\n\n    nav.enable = function () {\n        var self = this;\n\n        if (!self.isRunning) {\n            self.isRunning = true;\n            jQuery(function ($) {\n                self.init($);\n\n                self.reset();\n                self.win.on('hashchange', self.reset);\n\n                // Set scroll monitor\n                self.win.on('scroll', function () {\n                    if (!self.linkScroll) {\n                        self.winScroll = true;\n                    }\n                });\n                setInterval(function () { if (self.winScroll) self.onScroll(); }, 25);\n\n                // Set resize monitor\n                self.win.on('resize', function () {\n                    self.winResize = true;\n                });\n                setInterval(function () { if (self.winResize) self.onResize(); }, 25);\n                self.onResize();\n            });\n        };\n    };\n\n    nav.init = function ($) {\n        var doc = $(document),\n            self = this;\n\n        this.navBar = $('div.wy-side-scroll:first');\n        this.win = $(window);\n\n        // Set up javascript UX bits\n        $(document)\n            // Shift nav in mobile when clicking the menu.\n            .on('click', \"[data-toggle='wy-nav-top']\", function() {\n                $(\"[data-toggle='wy-nav-shift']\").toggleClass(\"shift\");\n                $(\"[data-toggle='rst-versions']\").toggleClass(\"shift\");\n            })\n\n            // Nav menu link click operations\n            .on('click', \".wy-menu-vertical .current ul li a\", function() {\n                var target = $(this);\n                // Close menu when you click a link.\n                $(\"[data-toggle='wy-nav-shift']\").removeClass(\"shift\");\n                $(\"[data-toggle='rst-versions']\").toggleClass(\"shift\");\n                // Handle dynamic display of l3 and l4 nav lists\n                self.toggleCurrent(target);\n                self.hashChange();\n            })\n            .on('click', \"[data-toggle='rst-current-version']\", function() {\n                $(\"[data-toggle='rst-versions']\").toggleClass(\"shift-up\");\n            })\n\n        // Make tables responsive\n        $(\"table.docutils:not(.field-list)\")\n            .wrap(\"<div class='wy-table-responsive'></div>\");\n\n        // Add expand links to all parents of nested ul\n        $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {\n            var link = $(this);\n                expand = $('<span class=\"toctree-expand\"></span>');\n            expand.on('click', function (ev) {\n                self.toggleCurrent(link);\n                ev.stopPropagation();\n                return false;\n            });\n            link.prepend(expand);\n        });\n    };\n\n    nav.reset = function () {\n        // Get anchor from URL and open up nested nav\n        var anchor = encodeURI(window.location.hash);\n        if (anchor) {\n            try {\n                var link = $('.wy-menu-vertical')\n                    .find('[href=\"' + anchor + '\"]');\n                $('.wy-menu-vertical li.toctree-l1 li.current')\n                    .removeClass('current');\n                link.closest('li.toctree-l2').addClass('current');\n                link.closest('li.toctree-l3').addClass('current');\n                link.closest('li.toctree-l4').addClass('current');\n            }\n            catch (err) {\n                console.log(\"Error expanding nav for anchor\", err);\n            }\n        }\n    };\n\n    nav.onScroll = function () {\n        this.winScroll = false;\n        var newWinPosition = this.win.scrollTop(),\n            winBottom = newWinPosition + this.winHeight,\n            navPosition = this.navBar.scrollTop(),\n            newNavPosition = navPosition + (newWinPosition - this.winPosition);\n        if (newWinPosition < 0 || winBottom > this.docHeight) {\n            return;\n        }\n        this.navBar.scrollTop(newNavPosition);\n        this.winPosition = newWinPosition;\n    };\n\n    nav.onResize = function () {\n        this.winResize = false;\n        this.winHeight = this.win.height();\n        this.docHeight = $(document).height();\n    };\n\n    nav.hashChange = function () {\n        this.linkScroll = true;\n        this.win.one('hashchange', function () {\n            this.linkScroll = false;\n        });\n    };\n\n    nav.toggleCurrent = function (elem) {\n        var parent_li = elem.closest('li');\n        parent_li.siblings('li.current').removeClass('current');\n        parent_li.siblings().find('li.current').removeClass('current');\n        parent_li.find('> ul li.current').removeClass('current');\n        parent_li.toggleClass('current');\n    }\n\n    return nav;\n};\n\nmodule.exports.ThemeNav = ThemeNav();\n\nif (typeof(window) != 'undefined') {\n    window.SphinxRtdTheme = { StickyNav: module.exports.ThemeNav };\n}\n\n},{\"jquery\":\"jquery\"}]},{},[\"sphinx-rtd-theme\"]);\n"
  },
  {
    "path": "docs/_static/language_data.js",
    "content": "/*\n * language_data.js\n * ~~~~~~~~~~~~~~~~\n *\n * This script contains the language-specific data used by searchtools.js,\n * namely the list of stopwords, stemmer, scorer and splitter.\n *\n * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\nvar stopwords = [\"a\", \"and\", \"are\", \"as\", \"at\", \"be\", \"but\", \"by\", \"for\", \"if\", \"in\", \"into\", \"is\", \"it\", \"near\", \"no\", \"not\", \"of\", \"on\", \"or\", \"such\", \"that\", \"the\", \"their\", \"then\", \"there\", \"these\", \"they\", \"this\", \"to\", \"was\", \"will\", \"with\"];\n\n\n/* Non-minified version is copied as a separate JS file, is available */\n\n/**\n * Porter Stemmer\n */\nvar Stemmer = function() {\n\n  var step2list = {\n    ational: 'ate',\n    tional: 'tion',\n    enci: 'ence',\n    anci: 'ance',\n    izer: 'ize',\n    bli: 'ble',\n    alli: 'al',\n    entli: 'ent',\n    eli: 'e',\n    ousli: 'ous',\n    ization: 'ize',\n    ation: 'ate',\n    ator: 'ate',\n    alism: 'al',\n    iveness: 'ive',\n    fulness: 'ful',\n    ousness: 'ous',\n    aliti: 'al',\n    iviti: 'ive',\n    biliti: 'ble',\n    logi: 'log'\n  };\n\n  var step3list = {\n    icate: 'ic',\n    ative: '',\n    alize: 'al',\n    iciti: 'ic',\n    ical: 'ic',\n    ful: '',\n    ness: ''\n  };\n\n  var c = \"[^aeiou]\";          // consonant\n  var v = \"[aeiouy]\";          // vowel\n  var C = c + \"[^aeiouy]*\";    // consonant sequence\n  var V = v + \"[aeiou]*\";      // vowel sequence\n\n  var mgr0 = \"^(\" + C + \")?\" + V + C;                      // [C]VC... is m>0\n  var meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\";    // [C]VC[V] is m=1\n  var mgr1 = \"^(\" + C + \")?\" + V + C + V + C;              // [C]VCVC... is m>1\n  var s_v   = \"^(\" + C + \")?\" + v;                         // vowel in stem\n\n  this.stemWord = function (w) {\n    var stem;\n    var suffix;\n    var firstch;\n    var origword = w;\n\n    if (w.length < 3)\n      return w;\n\n    var re;\n    var re2;\n    var re3;\n    var re4;\n\n    firstch = w.substr(0,1);\n    if (firstch == \"y\")\n      w = firstch.toUpperCase() + w.substr(1);\n\n    // Step 1a\n    re = /^(.+?)(ss|i)es$/;\n    re2 = /^(.+?)([^s])s$/;\n\n    if (re.test(w))\n      w = w.replace(re,\"$1$2\");\n    else if (re2.test(w))\n      w = w.replace(re2,\"$1$2\");\n\n    // Step 1b\n    re = /^(.+?)eed$/;\n    re2 = /^(.+?)(ed|ing)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      re = new RegExp(mgr0);\n      if (re.test(fp[1])) {\n        re = /.$/;\n        w = w.replace(re,\"\");\n      }\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1];\n      re2 = new RegExp(s_v);\n      if (re2.test(stem)) {\n        w = stem;\n        re2 = /(at|bl|iz)$/;\n        re3 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n        re4 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n        if (re2.test(w))\n          w = w + \"e\";\n        else if (re3.test(w)) {\n          re = /.$/;\n          w = w.replace(re,\"\");\n        }\n        else if (re4.test(w))\n          w = w + \"e\";\n      }\n    }\n\n    // Step 1c\n    re = /^(.+?)y$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(s_v);\n      if (re.test(stem))\n        w = stem + \"i\";\n    }\n\n    // Step 2\n    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step2list[suffix];\n    }\n\n    // Step 3\n    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step3list[suffix];\n    }\n\n    // Step 4\n    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n    re2 = /^(.+?)(s|t)(ion)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      if (re.test(stem))\n        w = stem;\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1] + fp[2];\n      re2 = new RegExp(mgr1);\n      if (re2.test(stem))\n        w = stem;\n    }\n\n    // Step 5\n    re = /^(.+?)e$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      re2 = new RegExp(meq1);\n      re3 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))\n        w = stem;\n    }\n    re = /ll$/;\n    re2 = new RegExp(mgr1);\n    if (re.test(w) && re2.test(w)) {\n      re = /.$/;\n      w = w.replace(re,\"\");\n    }\n\n    // and turn initial Y back to y\n    if (firstch == \"y\")\n      w = firstch.toLowerCase() + w.substr(1);\n    return w;\n  }\n}\n\n"
  },
  {
    "path": "docs/_static/misty-light-windows.css",
    "content": "@charset \"UTF-8\";\n/*!\nMisty Light\nBrought to you with ❤️ by E-Tiger Studio, 2017-2019\nhttps://github.com/etigerstudio/typora-misty-theme\n */\n:root {\n  --control-text-color: #777;\n  --side-bar-bg-color: #f6f8fa\n}\nhtml {\n  font-size: 16px;\n  -webkit-font-smoothing: subpixel-antialiased\n}\nbody {\n  font-family: \"SF UI Text\",\"PingFang SC\",-apple-system,-apple-system-body,BlinkMacSystemFont,\"Segoe UI\",\"Microsoft YaHei\",\"微软雅黑\",Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";\n  color: #24292e;\n  line-height: 1.5;\n  font-weight: 400;\n  -webkit-font-smoothing: unset\n}\n#write {\n  max-width: 860px;\n  margin: 0 auto;\n  padding: 20px 30px 100px\n}\n#write > ol:first-child,\n#write > ul:first-child {\n  margin-top: 30px\n}\nbody > :first-child {\n  margin-top: 0!important\n}\nbody > :last-child {\n  margin-bottom: 0!important\n}\na {\n  color: #4183c4\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n  position: relative;\n  margin-top: 1.8rem;\n  margin-bottom: 1rem;\n  line-height: 1.4;\n  cursor: text;\n  color: #142331\n}\nh1:hover a.anchor,\nh2:hover a.anchor,\nh3:hover a.anchor,\nh4:hover a.anchor,\nh5:hover a.anchor,\nh6:hover a.anchor {\n  text-decoration: none\n}\nh1 code,\nh1 tt,\nh2 code,\nh2 tt,\nh3 code,\nh3 tt,\nh4 code,\nh4 tt,\nh5 code,\nh5 tt,\nh6 code,\nh6 tt {\n  font-size: inherit\n}\nh1 {\n  text-align: center;\n  padding-bottom: .3em;\n  font-size: 2.25em;\n  line-height: 1.2;\n  margin: 1em auto 1.2em\n}\nh1:after {\n  border-bottom: 2px dashed #afec9e;\n  content: '';\n  width: 100px;\n  display: block;\n  margin: .2em auto 0;\n  height: 2px\n}\nh2 {\n  font-size: 1.75em;\n  padding-left: 9px;\n  line-height: 1.4;\n  border-left: 6px solid #cce5ff\n}\nh3 {\n  font-size: 1.5em;\n  line-height: 1.43\n}\nh3:before {\n  border-radius: 50%;\n  background-color: #9ed0ff;\n  content: '';\n  width: 6px;\n  display: inline-block;\n  height: 6px;\n  vertical-align: middle;\n  margin-bottom: .18em;\n  margin-right: 8px\n}\n#write > h3.md-focus:before,\n#write > h4.md-focus:before {\n  background-color: transparent;\n  width: auto;\n  height: auto\n}\nh4 {\n  font-size: 1.25em\n}\nh4:before {\n  background-color: #9ed0ff;\n  content: '';\n  width: 6px;\n  display: inline-block;\n  height: 2px;\n  vertical-align: middle;\n  margin-bottom: .18em;\n  margin-right: 8px\n}\nh5 {\n  font-size: 1em\n}\nh6 {\n  font-size: 1em;\n  color: #777\n}\nblockquote,\ndl,\nol,\np,\ntable,\nul {\n  margin: .8em 0\n}\nli > ol,\nli > ul {\n  margin: 0\n}\nhr {\n  height: .25em;\n  padding: 0;\n  margin: 24px 0;\n  background-color: #e1e4e8;\n  border: 0\n}\na:first-child h1,\na:first-child h2,\na:first-child h3,\na:first-child h4,\na:first-child h5,\na:first-child h6,\nbody>h1:first-child,\nbody>h1:first-child+h2,\nbody>h2:first-child,\nbody>h3:first-child,\nbody>h4:first-child,\nbody>h5:first-child,\nbody>h6:first-child {\n  margin-top: 0;\n  padding-top: 0\n}\nh1 p,\nh2 p,\nh3 p,\nh4 p,\nh5 p,\nh6 p {\n  margin-top: 0\n}\nli p.first {\n  display: inline-block\n}\nol,\nul {\n  padding-left: 30px\n}\nol:first-child,\nul:first-child {\n  margin-top: 0\n}\nol:last-child,\nul:last-child {\n  margin-bottom: 0\n}\nblockquote {\n  border-left: 4px dotted #e5e8e8;\n  padding: 0 12px;\n  color: #444;\n  font-size: .9em\n}\nblockquote blockquote {\n  padding-right: 0\n}\ntable {\n  padding: 0;\n  word-break: initial\n}\ntable tr {\n  border-top: 1px solid #dadfe6;\n  margin: 0;\n  padding: 0\n}\ntable.md-table tr:nth-child(2n) {\n  background-color: #fafbfc\n}\ntable tr td,\ntable tr th {\n  border: 1px solid #dadfe6;\n  text-align: left;\n  margin: 0;\n  padding: 6px 13px\n}\ntable tr td:first-child,\ntable tr th:first-child {\n  margin-top: 0\n}\ntable tr td:last-child,\ntable tr th:last-child {\n  margin-bottom: 0\n}\n.CodeMirror-gutters {\n  border-right: 1px solid #ddd\n}\n.md-fences,\ncode,\ntt {\n  font-size: 90%;\n  border-radius: 3px;\n  font-family: \"SF Mono\",Consolas,\"Liberation Mono\",Menlo,Courier,monospace,\"PingFang SC\",\"Microsoft YaHei\",\"微软雅黑\"\n}\ncode,\ntt {\n  margin: 0 2px;\n  padding: 2px 4px;\n  background-color: #e2f0ff\n}\n.md-fences {\n  background-color: #f6f8fa;\n  margin-bottom: 15px;\n  margin-top: 15px;\n  padding: 12px 1em\n}\n.md-task-list-item > input {\n  margin-left: -1.45em;\n  margin-top: calc(1em - 10px)\n}\n@media print {\n  body {\n    font-size: 11px;\n    font-weight: 400\n  }\n  pre,\n  table {\n    page-break-inside: avoid\n  }\n  pre {\n    word-wrap: break-word\n  }\n}\n#write pre.md-meta-block {\n  padding: 1rem;\n  font-size: 85%;\n  line-height: 1.45;\n  background-color: #f7faf6;\n  border: 0;\n  border-radius: 3px;\n  color: #777;\n  margin-top: 0!important\n}\n.mathjax-block > .code-tooltip {\n  bottom: .375rem\n}\n#write > h3.md-focus:before {\n  left: -1.5625rem;\n  top: .375rem\n}\n#write>h4.md-focus:before,\n#write>h5.md-focus:before,\n#write>h6.md-focus:before {\n  left: -1.5625rem;\n  top: .285714286rem\n}\n.md-image > .md-meta {\n  border: 1px solid #ddd;\n  border-radius: 3px;\n  font-family: \"SF Mono\",Consolas,\"PingFang SC\",\"Liberation Mono\",Courier,monospace,\"Microsoft YaHei\",\"微软雅黑\";\n  padding: 2px 4px 0;\n  font-size: .9em;\n  color: inherit\n}\n.md-tag {\n  color: inherit\n}\n.md-toc {\n  margin-top: 20px;\n  padding-bottom: 20px\n}\n.sidebar-tabs {\n  border-bottom: none\n}\n#typora-quick-open {\n  border: 1px solid #ddd;\n  background-color: #f8f8f8\n}\n#typora-quick-open-item {\n  background-color: #fafafa;\n  border-color: #fefefe #e5e5e5 #e5e5e5 #eee;\n  border-style: solid;\n  border-width: 1px\n}\n.typora-quick-open-item {\n  padding-top: 3px\n}\n.typora-quick-open-list {\n  margin-top: 4px\n}\n.typora-quick-open-item-path {\n  margin-top: -2px\n}\n#md-notification:before {\n  top: 10px\n}\n.on-focus-mode blockquote {\n  border-left-color: rgba(85,85,85,.12)\n}\n.context-menu,\n.megamenu-content,\nfooter,\nheader {\n  font-family: \"SF UI Text\",\"PingFang SC\",-apple-system,-apple-system-body,BlinkMacSystemFont,\"Segoe UI\",\"Microsoft YaHei\",\"微软雅黑\",Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\"\n}\n.file-node-content:hover .file-node-icon,\n.file-node-content:hover .file-node-open-state {\n  visibility: visible\n}\n.mac-seamless-mode #typora-sidebar {\n  background-color: var(--side-bar-bg-color)\n}\n.md-lang {\n  color: #b4654d\n}\n.pin-outline #outline-content .outline-active strong,\n.pin-outline .outline-active {\n  color: #232323;\n  font-weight: 600\n}\n.outline-label {\n  color: #646464;\n  font-weight: 400\n}\n.file-list-item-summary {\n  font-family: \"SF UI Text\",\"PingFang SC\",-apple-system,-apple-system-body,BlinkMacSystemFont,\"Segoe UI\",\"Microsoft YaHei\",\"微软雅黑\",Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\"\n}\nb,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nstrong {\n  font-weight: 600\n}\nh1,\ntable tr th {\n  font-weight: 400\n}\n.file-list-item-file-name {\n  font-weight: 500\n}"
  },
  {
    "path": "docs/_static/nature.css",
    "content": "/*\n * nature.css_t\n * ~~~~~~~~~~~~\n *\n * Sphinx stylesheet -- nature theme.\n *\n * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n \n@import url(\"basic.css\");\n \n/* -- page layout ----------------------------------------------------------- */\n \nbody {\n    font-family: Arial, sans-serif;\n    font-size: 100%;\n    background-color: #fff;\n    color: #555;\n    margin: 0;\n    padding: 0;\n}\n\ndiv.documentwrapper {\n    float: left;\n    width: 100%;\n}\n\ndiv.bodywrapper {\n    margin: 0 0 0 230px;\n}\n\nhr {\n    border: 1px solid #B1B4B6;\n}\n \ndiv.document {\n    background-color: #eee;\n}\n \ndiv.body {\n    background-color: #ffffff;\n    color: #3E4349;\n    padding: 0 30px 30px 30px;\n    font-size: 0.9em;\n}\n \ndiv.footer {\n    color: #555;\n    width: 100%;\n    padding: 13px 0;\n    text-align: center;\n    font-size: 75%;\n}\n \ndiv.footer a {\n    color: #444;\n    text-decoration: underline;\n}\n \ndiv.related {\n    background-color: #6BA81E;\n    line-height: 32px;\n    color: #fff;\n    text-shadow: 0px 1px 0 #444;\n    font-size: 0.9em;\n}\n \ndiv.related a {\n    color: #E2F3CC;\n}\n \ndiv.sphinxsidebar {\n    font-size: 0.75em;\n    line-height: 1.5em;\n}\n\ndiv.sphinxsidebarwrapper{\n    padding: 20px 0;\n}\n \ndiv.sphinxsidebar h3,\ndiv.sphinxsidebar h4 {\n    font-family: Arial, sans-serif;\n    color: #222;\n    font-size: 1.2em;\n    font-weight: normal;\n    margin: 0;\n    padding: 5px 10px;\n    background-color: #ddd;\n    text-shadow: 1px 1px 0 white\n}\n\ndiv.sphinxsidebar h4{\n    font-size: 1.1em;\n}\n \ndiv.sphinxsidebar h3 a {\n    color: #444;\n}\n \n \ndiv.sphinxsidebar p {\n    color: #888;\n    padding: 5px 20px;\n}\n \ndiv.sphinxsidebar p.topless {\n}\n \ndiv.sphinxsidebar ul {\n    margin: 10px 20px;\n    padding: 0;\n    color: #000;\n}\n \ndiv.sphinxsidebar a {\n    color: #444;\n}\n \ndiv.sphinxsidebar input {\n    border: 1px solid #ccc;\n    font-family: sans-serif;\n    font-size: 1em;\n}\n\ndiv.sphinxsidebar .searchformwrapper {\n    margin-left: 20px;\n    margin-right: 20px;\n}\n\n/* -- body styles ----------------------------------------------------------- */\n \na {\n    color: #005B81;\n    text-decoration: none;\n}\n \na:hover {\n    color: #E32E00;\n    text-decoration: underline;\n}\n \ndiv.body h1,\ndiv.body h2,\ndiv.body h3,\ndiv.body h4,\ndiv.body h5,\ndiv.body h6 {\n    font-family: Arial, sans-serif;\n    background-color: #BED4EB;\n    font-weight: normal;\n    color: #212224;\n    margin: 30px 0px 10px 0px;\n    padding: 5px 0 5px 10px;\n    text-shadow: 0px 1px 0 white\n}\n \ndiv.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; }\ndiv.body h2 { font-size: 150%; background-color: #C8D5E3; }\ndiv.body h3 { font-size: 120%; background-color: #D8DEE3; }\ndiv.body h4 { font-size: 110%; background-color: #D8DEE3; }\ndiv.body h5 { font-size: 100%; background-color: #D8DEE3; }\ndiv.body h6 { font-size: 100%; background-color: #D8DEE3; }\n \na.headerlink {\n    color: #c60f0f;\n    font-size: 0.8em;\n    padding: 0 4px 0 4px;\n    text-decoration: none;\n}\n \na.headerlink:hover {\n    background-color: #c60f0f;\n    color: white;\n}\n \ndiv.body p, div.body dd, div.body li {\n    line-height: 1.5em;\n}\n \ndiv.admonition p.admonition-title + p {\n    display: inline;\n}\n\ndiv.highlight{\n    background-color: white;\n}\n\ndiv.note {\n    background-color: #eee;\n    border: 1px solid #ccc;\n}\n \ndiv.seealso {\n    background-color: #ffc;\n    border: 1px solid #ff6;\n}\n \ndiv.topic {\n    background-color: #eee;\n}\n \ndiv.warning {\n    background-color: #ffe4e4;\n    border: 1px solid #f66;\n}\n \np.admonition-title {\n    display: inline;\n}\n \np.admonition-title:after {\n    content: \":\";\n}\n \npre {\n    padding: 10px;\n    background-color: White;\n    color: #222;\n    line-height: 1.2em;\n    border: 1px solid #C6C9CB;\n    font-size: 1.1em;\n    margin: 1.5em 0 1.5em 0;\n    -webkit-box-shadow: 1px 1px 1px #d8d8d8;\n    -moz-box-shadow: 1px 1px 1px #d8d8d8;\n}\n \ncode {\n    background-color: #ecf0f3;\n    color: #222;\n    /* padding: 1px 2px; */\n    font-size: 1.1em;\n    font-family: monospace;\n}\n\n.viewcode-back {\n    font-family: Arial, sans-serif;\n}\n\ndiv.viewcode-block:target {\n    background-color: #f4debf;\n    border-top: 1px solid #ac9;\n    border-bottom: 1px solid #ac9;\n}\n\ndiv.code-block-caption {\n    background-color: #ddd;\n    color: #222;\n    border: 1px solid #C6C9CB;\n}"
  },
  {
    "path": "docs/_static/pygments.css",
    "content": "pre { line-height: 125%; margin: 0; }\ntd.linenos pre { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; }\ntd.linenos pre.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.highlight .hll { background-color: #ffffcc }\n.highlight { background: #eeffcc; }\n.highlight .c { color: #408090; font-style: italic } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { color: #007020; font-weight: bold } /* Keyword */\n.highlight .o { color: #666666 } /* Operator */\n.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */\n.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #007020 } /* Comment.Preproc */\n.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */\n.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #333333 } /* Generic.Output */\n.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0044DD } /* Generic.Traceback */\n.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #007020 } /* Keyword.Pseudo */\n.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #902000 } /* Keyword.Type */\n.highlight .m { color: #208050 } /* Literal.Number */\n.highlight .s { color: #4070a0 } /* Literal.String */\n.highlight .na { color: #4070a0 } /* Name.Attribute */\n.highlight .nb { color: #007020 } /* Name.Builtin */\n.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */\n.highlight .no { color: #60add5 } /* Name.Constant */\n.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */\n.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #007020 } /* Name.Exception */\n.highlight .nf { color: #06287e } /* Name.Function */\n.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */\n.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #bb60d5 } /* Name.Variable */\n.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mb { color: #208050 } /* Literal.Number.Bin */\n.highlight .mf { color: #208050 } /* Literal.Number.Float */\n.highlight .mh { color: #208050 } /* Literal.Number.Hex */\n.highlight .mi { color: #208050 } /* Literal.Number.Integer */\n.highlight .mo { color: #208050 } /* Literal.Number.Oct */\n.highlight .sa { color: #4070a0 } /* Literal.String.Affix */\n.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */\n.highlight .sc { color: #4070a0 } /* Literal.String.Char */\n.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */\n.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #4070a0 } /* Literal.String.Double */\n.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */\n.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */\n.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */\n.highlight .sx { color: #c65d09 } /* Literal.String.Other */\n.highlight .sr { color: #235388 } /* Literal.String.Regex */\n.highlight .s1 { color: #4070a0 } /* Literal.String.Single */\n.highlight .ss { color: #517918 } /* Literal.String.Symbol */\n.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */\n.highlight .fm { color: #06287e } /* Name.Function.Magic */\n.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */\n.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */\n.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */\n.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */\n.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */"
  },
  {
    "path": "docs/_static/pyramid.css",
    "content": "/*\n * pyramid.css_t\n * ~~~~~~~~~~~~\n *\n * Sphinx stylesheet -- pylons theme.\n *\n * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n \n@import url(\"basic.css\");\n \n/* -- page layout ----------------------------------------------------------- */\n \nbody {\n    font-family: \"Nobile\", sans-serif;\n    font-size: 100%;\n    background-color: #393939;\n    color: #ffffff;\n    margin: 0;\n    padding: 0;\n}\n\ndiv.documentwrapper {\n    float: left;\n    width: 100%;\n}\n\ndiv.bodywrapper {\n    margin: 0 0 0 230px;\n}\n\nhr {\n    border: 1px solid #B1B4B6;\n}\n \ndiv.document {\n    background-color: #eee;\n}\n\ndiv.header {\n    width:100%;\n    background: #f4ad32 url(headerbg.png) repeat-x 0 top;\n    border-bottom: 2px solid #ffffff;\n}\n\ndiv.logo {\n    text-align: center;\n    padding-top: 10px;\n}\n\ndiv.body {\n    background-color: #ffffff;\n    color: #3E4349;\n    padding: 0 30px 30px 30px;\n    font-size: 1em;\n    border: 2px solid #ddd;\n    border-right-style: none;\n    overflow: auto;\n}\n \ndiv.footer {\n    color: #ffffff;\n    width: 100%;\n    padding: 13px 0;\n    text-align: center;\n    font-size: 75%;\n    background: transparent;\n    clear:both;\n}\n \ndiv.footer a {\n    color: #ffffff;\n    text-decoration: none;\n}\n\ndiv.footer a:hover {\n    color: #e88f00;\n    text-decoration: underline;\n}\n \ndiv.related {\n    line-height: 30px;\n    color: #373839;\n    font-size: 0.8em;\n    background-color: #eee;\n}\n \ndiv.related a {\n    color: #1b61d6;\n}\n\ndiv.related ul {\n    padding-left: calc(230px + 10px);\n}\n \ndiv.sphinxsidebar {\n    font-size: 0.75em;\n    line-height: 1.5em;\n}\n\ndiv.sphinxsidebarwrapper{\n    padding: 10px 0;\n}\n \ndiv.sphinxsidebar h3,\ndiv.sphinxsidebar h4 {\n    font-family: \"Neuton\", sans-serif;\n    color: #373839;\n    font-size: 1.4em;\n    font-weight: normal;\n    margin: 0;\n    padding: 5px 10px;\n    border-bottom: 2px solid #ddd;\n}\n\ndiv.sphinxsidebar h4{\n    font-size: 1.3em;\n}\n \ndiv.sphinxsidebar h3 a {\n    color: #000000;\n}\n \n \ndiv.sphinxsidebar p {\n    color: #888;\n    padding: 5px 20px;\n}\n \ndiv.sphinxsidebar p.topless {\n}\n \ndiv.sphinxsidebar ul {\n    margin: 10px 20px;\n    padding: 0;\n    color: #373839;\n}\n \ndiv.sphinxsidebar a {\n    color: #444;\n}\n \ndiv.sphinxsidebar input {\n    border: 1px solid #ccc;\n    font-family: sans-serif;\n    font-size: 1em;\n}\n\ndiv.sphinxsidebar .searchformwrapper {\n    margin-left: 20px;\n    margin-right: 20px;\n}\n\n/* -- sidebars -------------------------------------------------------------- */\n\ndiv.sidebar {\n    margin: 0 0 0.5em 1em;\n    border: 2px solid #c6d880;\n    background-color: #e6efc2;\n    width: 40%;\n    float: right;\n    border-right-style: none;\n    border-left-style: none;\n    padding: 10px 20px;\n}\n\np.sidebar-title {\n    font-weight: bold;\n}\n\n/* -- body styles ----------------------------------------------------------- */\n \na, a .pre {\n    color: #1b61d6;\n    text-decoration: none;\n}\n \na:hover, a:hover .pre {\n    text-decoration: underline;\n}\n \ndiv.body h1,\ndiv.body h2,\ndiv.body h3,\ndiv.body h4,\ndiv.body h5,\ndiv.body h6 {\n    font-family: \"Neuton\", sans-serif;\n    background-color: #ffffff;\n    font-weight: normal;\n    color: #373839;\n    margin: 30px 0px 10px 0px;\n    padding: 5px 0;\n}\n \ndiv.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; }\ndiv.body h2 { font-size: 150%; background-color: #ffffff; }\ndiv.body h3 { font-size: 120%; background-color: #ffffff; }\ndiv.body h4 { font-size: 110%; background-color: #ffffff; }\ndiv.body h5 { font-size: 100%; background-color: #ffffff; }\ndiv.body h6 { font-size: 100%; background-color: #ffffff; }\n \na.headerlink {\n    color: #1b61d6;\n    font-size: 0.8em;\n    padding: 0 4px 0 4px;\n    text-decoration: none;\n}\n \na.headerlink:hover {\n    text-decoration: underline;\n}\n \ndiv.body p, div.body dd, div.body li {\n    line-height: 1.5em;\n}\n \ndiv.admonition p.admonition-title + p {\n    display: inline;\n}\n\ndiv.admonition {\n    background: #eeeeec;\n    border: 2px solid #babdb6;\n    border-right-style: none;\n    border-left-style: none;\n    padding: 10px 20px 10px 60px;\n}\n\ndiv.highlight{\n    background-color: white;\n}\n\ndiv.note {\n    border: 2px solid #7a9eec;\n    border-right-style: none;\n    border-left-style: none;\n    padding: 10px 20px 10px 60px;\n    background: #e1ecfe url(dialog-note.png) no-repeat 10px 8px;\n}\n \ndiv.seealso {\n    background: #fff6bf url(dialog-seealso.png) no-repeat 10px 8px;\n    border: 2px solid #ffd324;\n    border-left-style: none;\n    border-right-style: none;\n    padding: 10px 20px 10px 60px;\n}\n \ndiv.topic {\n    background: #eeeeee;\n    border: 2px solid #C6C9CB;\n    padding: 10px 20px;\n    border-right-style: none;\n    border-left-style: none;\n}\n \ndiv.warning {\n    background: #fbe3e4 url(dialog-warning.png) no-repeat 10px 8px;\n    border: 2px solid #fbc2c4;\n    border-right-style: none;\n    border-left-style: none;\n    padding: 10px 20px 10px 60px;\n}\n\ndiv.admonition-todo {\n    background: #f2d9b4 url(dialog-todo.png) no-repeat 10px 8px;\n    border: 2px solid #e9b96e;\n    border-right-style: none;\n    border-left-style: none;\n    padding: 10px 20px 10px 60px;\n}\n \ndiv.note p.admonition-title,\ndiv.warning p.admonition-title,\ndiv.seealso p.admonition-title,\ndiv.admonition-todo p.admonition-title {\n    display: none;\n}\n \np.admonition-title:after {\n    content: \":\";\n}\n \npre {\n    padding: 10px;\n    background-color: #fafafa;\n    color: #222;\n    line-height: 1.2em;\n    border: 2px solid #C6C9CB;\n    font-size: 1.1em;\n    margin: 1.5em 0 1.5em 0;\n    border-right-style: none;\n    border-left-style: none;\n}\n \ncode {\n    background-color: transparent;\n    color: #222;\n    font-size: 1.1em;\n    font-family: monospace;\n}\n\n.viewcode-back {\n    font-family: \"Nobile\", sans-serif;\n}\n\ndiv.viewcode-block:target {\n    background-color: #fff6bf;\n    border: 2px solid #ffd324;\n    border-left-style: none;\n    border-right-style: none;\n    padding: 10px 20px;\n}\n\ntable.highlighttable {\n    width: 100%;\n}\n\ntable.highlighttable td {\n    padding: 0;\n}\n\na em.std-term {\n   color: #007f00;\n}\n\na:hover em.std-term {\n    text-decoration: underline;\n}\n\n.download {\n    font-family: \"Nobile\", sans-serif;\n    font-weight: normal;\n    font-style: normal;\n}\n\ncode.xref {\n    font-weight: normal;\n    font-style: normal;\n}\n\ndiv.code-block-caption {\n    background-color: #ddd;\n    color: #222;\n}"
  },
  {
    "path": "docs/_static/searchtools.js",
    "content": "/*\n * searchtools.js_t\n * ~~~~~~~~~~~~~~~~\n *\n * Sphinx JavaScript utilities for the full-text search.\n *\n * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n\n/* Non-minified version JS is _stemmer.js if file is provided */ \n/**\n * Porter Stemmer\n */\nvar Stemmer = function() {\n\n  var step2list = {\n    ational: 'ate',\n    tional: 'tion',\n    enci: 'ence',\n    anci: 'ance',\n    izer: 'ize',\n    bli: 'ble',\n    alli: 'al',\n    entli: 'ent',\n    eli: 'e',\n    ousli: 'ous',\n    ization: 'ize',\n    ation: 'ate',\n    ator: 'ate',\n    alism: 'al',\n    iveness: 'ive',\n    fulness: 'ful',\n    ousness: 'ous',\n    aliti: 'al',\n    iviti: 'ive',\n    biliti: 'ble',\n    logi: 'log'\n  };\n\n  var step3list = {\n    icate: 'ic',\n    ative: '',\n    alize: 'al',\n    iciti: 'ic',\n    ical: 'ic',\n    ful: '',\n    ness: ''\n  };\n\n  var c = \"[^aeiou]\";          // consonant\n  var v = \"[aeiouy]\";          // vowel\n  var C = c + \"[^aeiouy]*\";    // consonant sequence\n  var V = v + \"[aeiou]*\";      // vowel sequence\n\n  var mgr0 = \"^(\" + C + \")?\" + V + C;                      // [C]VC... is m>0\n  var meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\";    // [C]VC[V] is m=1\n  var mgr1 = \"^(\" + C + \")?\" + V + C + V + C;              // [C]VCVC... is m>1\n  var s_v   = \"^(\" + C + \")?\" + v;                         // vowel in stem\n\n  this.stemWord = function (w) {\n    var stem;\n    var suffix;\n    var firstch;\n    var origword = w;\n\n    if (w.length < 3)\n      return w;\n\n    var re;\n    var re2;\n    var re3;\n    var re4;\n\n    firstch = w.substr(0,1);\n    if (firstch == \"y\")\n      w = firstch.toUpperCase() + w.substr(1);\n\n    // Step 1a\n    re = /^(.+?)(ss|i)es$/;\n    re2 = /^(.+?)([^s])s$/;\n\n    if (re.test(w))\n      w = w.replace(re,\"$1$2\");\n    else if (re2.test(w))\n      w = w.replace(re2,\"$1$2\");\n\n    // Step 1b\n    re = /^(.+?)eed$/;\n    re2 = /^(.+?)(ed|ing)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      re = new RegExp(mgr0);\n      if (re.test(fp[1])) {\n        re = /.$/;\n        w = w.replace(re,\"\");\n      }\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1];\n      re2 = new RegExp(s_v);\n      if (re2.test(stem)) {\n        w = stem;\n        re2 = /(at|bl|iz)$/;\n        re3 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n        re4 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n        if (re2.test(w))\n          w = w + \"e\";\n        else if (re3.test(w)) {\n          re = /.$/;\n          w = w.replace(re,\"\");\n        }\n        else if (re4.test(w))\n          w = w + \"e\";\n      }\n    }\n\n    // Step 1c\n    re = /^(.+?)y$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(s_v);\n      if (re.test(stem))\n        w = stem + \"i\";\n    }\n\n    // Step 2\n    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step2list[suffix];\n    }\n\n    // Step 3\n    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step3list[suffix];\n    }\n\n    // Step 4\n    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n    re2 = /^(.+?)(s|t)(ion)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      if (re.test(stem))\n        w = stem;\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1] + fp[2];\n      re2 = new RegExp(mgr1);\n      if (re2.test(stem))\n        w = stem;\n    }\n\n    // Step 5\n    re = /^(.+?)e$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      re2 = new RegExp(meq1);\n      re3 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))\n        w = stem;\n    }\n    re = /ll$/;\n    re2 = new RegExp(mgr1);\n    if (re.test(w) && re2.test(w)) {\n      re = /.$/;\n      w = w.replace(re,\"\");\n    }\n\n    // and turn initial Y back to y\n    if (firstch == \"y\")\n      w = firstch.toLowerCase() + w.substr(1);\n    return w;\n  }\n}\n\n\n\n/**\n * Simple result scoring code.\n */\nvar Scorer = {\n  // Implement the following function to further tweak the score for each result\n  // The function takes a result array [filename, title, anchor, descr, score]\n  // and returns the new score.\n  /*\n  score: function(result) {\n    return result[4];\n  },\n  */\n\n  // query matches the full name of an object\n  objNameMatch: 11,\n  // or matches in the last dotted part of the object name\n  objPartialMatch: 6,\n  // Additive scores depending on the priority of the object\n  objPrio: {0:  15,   // used to be importantResults\n            1:  5,   // used to be objectResults\n            2: -5},  // used to be unimportantResults\n  //  Used when the priority is not in the mapping.\n  objPrioDefault: 0,\n\n  // query found in title\n  title: 15,\n  // query found in terms\n  term: 5\n};\n\n\n\n\n\nvar splitChars = (function() {\n    var result = {};\n    var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,\n         1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,\n         2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,\n         2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,\n         3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,\n         3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,\n         4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,\n         8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,\n         11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,\n         43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];\n    var i, j, start, end;\n    for (i = 0; i < singles.length; i++) {\n        result[singles[i]] = true;\n    }\n    var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],\n         [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],\n         [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],\n         [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],\n         [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],\n         [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],\n         [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],\n         [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],\n         [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],\n         [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],\n         [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],\n         [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],\n         [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],\n         [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],\n         [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],\n         [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],\n         [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],\n         [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],\n         [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],\n         [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],\n         [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],\n         [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],\n         [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],\n         [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],\n         [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],\n         [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],\n         [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],\n         [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],\n         [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],\n         [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],\n         [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],\n         [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],\n         [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],\n         [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],\n         [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],\n         [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],\n         [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],\n         [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],\n         [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],\n         [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],\n         [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],\n         [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],\n         [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],\n         [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],\n         [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],\n         [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],\n         [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],\n         [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],\n         [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];\n    for (i = 0; i < ranges.length; i++) {\n        start = ranges[i][0];\n        end = ranges[i][1];\n        for (j = start; j <= end; j++) {\n            result[j] = true;\n        }\n    }\n    return result;\n})();\n\nfunction splitQuery(query) {\n    var result = [];\n    var start = -1;\n    for (var i = 0; i < query.length; i++) {\n        if (splitChars[query.charCodeAt(i)]) {\n            if (start !== -1) {\n                result.push(query.slice(start, i));\n                start = -1;\n            }\n        } else if (start === -1) {\n            start = i;\n        }\n    }\n    if (start !== -1) {\n        result.push(query.slice(start));\n    }\n    return result;\n}\n\n\n\n\n/**\n * Search Module\n */\nvar Search = {\n\n  _index : null,\n  _queued_query : null,\n  _pulse_status : -1,\n\n  init : function() {\n      var params = $.getQueryParameters();\n      if (params.q) {\n          var query = params.q[0];\n          $('input[name=\"q\"]')[0].value = query;\n          this.performSearch(query);\n      }\n  },\n\n  loadIndex : function(url) {\n    $.ajax({type: \"GET\", url: url, data: null,\n            dataType: \"script\", cache: true,\n            complete: function(jqxhr, textstatus) {\n              if (textstatus != \"success\") {\n                document.getElementById(\"searchindexloader\").src = url;\n              }\n            }});\n  },\n\n  setIndex : function(index) {\n    var q;\n    this._index = index;\n    if ((q = this._queued_query) !== null) {\n      this._queued_query = null;\n      Search.query(q);\n    }\n  },\n\n  hasIndex : function() {\n      return this._index !== null;\n  },\n\n  deferQuery : function(query) {\n      this._queued_query = query;\n  },\n\n  stopPulse : function() {\n      this._pulse_status = 0;\n  },\n\n  startPulse : function() {\n    if (this._pulse_status >= 0)\n        return;\n    function pulse() {\n      var i;\n      Search._pulse_status = (Search._pulse_status + 1) % 4;\n      var dotString = '';\n      for (i = 0; i < Search._pulse_status; i++)\n        dotString += '.';\n      Search.dots.text(dotString);\n      if (Search._pulse_status > -1)\n        window.setTimeout(pulse, 500);\n    }\n    pulse();\n  },\n\n  /**\n   * perform a search for something (or wait until index is loaded)\n   */\n  performSearch : function(query) {\n    // create the required interface elements\n    this.out = $('#search-results');\n    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);\n    this.dots = $('<span></span>').appendTo(this.title);\n    this.status = $('<p style=\"display: none\"></p>').appendTo(this.out);\n    this.output = $('<ul class=\"search\"/>').appendTo(this.out);\n\n    $('#search-progress').text(_('Preparing search...'));\n    this.startPulse();\n\n    // index already loaded, the browser was quick!\n    if (this.hasIndex())\n      this.query(query);\n    else\n      this.deferQuery(query);\n  },\n\n  /**\n   * execute search (requires search index to be loaded)\n   */\n  query : function(query) {\n    var i;\n    var stopwords = [\"a\",\"and\",\"are\",\"as\",\"at\",\"be\",\"but\",\"by\",\"for\",\"if\",\"in\",\"into\",\"is\",\"it\",\"near\",\"no\",\"not\",\"of\",\"on\",\"or\",\"such\",\"that\",\"the\",\"their\",\"then\",\"there\",\"these\",\"they\",\"this\",\"to\",\"was\",\"will\",\"with\"];\n\n    // stem the searchterms and add them to the correct list\n    var stemmer = new Stemmer();\n    var searchterms = [];\n    var excluded = [];\n    var hlterms = [];\n    var tmp = splitQuery(query);\n    var objectterms = [];\n    for (i = 0; i < tmp.length; i++) {\n      if (tmp[i] !== \"\") {\n          objectterms.push(tmp[i].toLowerCase());\n      }\n\n      if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\\d+$/) ||\n          tmp[i] === \"\") {\n        // skip this \"word\"\n        continue;\n      }\n      // stem the word\n      var word = stemmer.stemWord(tmp[i].toLowerCase());\n      // prevent stemmer from cutting word smaller than two chars\n      if(word.length < 3 && tmp[i].length >= 3) {\n        word = tmp[i];\n      }\n      var toAppend;\n      // select the correct list\n      if (word[0] == '-') {\n        toAppend = excluded;\n        word = word.substr(1);\n      }\n      else {\n        toAppend = searchterms;\n        hlterms.push(tmp[i].toLowerCase());\n      }\n      // only add if not already in the list\n      if (!$u.contains(toAppend, word))\n        toAppend.push(word);\n    }\n    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(\" \"));\n\n    // console.debug('SEARCH: searching for:');\n    // console.info('required: ', searchterms);\n    // console.info('excluded: ', excluded);\n\n    // prepare search\n    var terms = this._index.terms;\n    var titleterms = this._index.titleterms;\n\n    // array of [filename, title, anchor, descr, score]\n    var results = [];\n    $('#search-progress').empty();\n\n    // lookup as object\n    for (i = 0; i < objectterms.length; i++) {\n      var others = [].concat(objectterms.slice(0, i),\n                             objectterms.slice(i+1, objectterms.length));\n      results = results.concat(this.performObjectSearch(objectterms[i], others));\n    }\n\n    // lookup as search terms in fulltext\n    results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));\n\n    // let the scorer override scores with a custom scoring function\n    if (Scorer.score) {\n      for (i = 0; i < results.length; i++)\n        results[i][4] = Scorer.score(results[i]);\n    }\n\n    // now sort the results by score (in opposite order of appearance, since the\n    // display function below uses pop() to retrieve items) and then\n    // alphabetically\n    results.sort(function(a, b) {\n      var left = a[4];\n      var right = b[4];\n      if (left > right) {\n        return 1;\n      } else if (left < right) {\n        return -1;\n      } else {\n        // same score: sort alphabetically\n        left = a[1].toLowerCase();\n        right = b[1].toLowerCase();\n        return (left > right) ? -1 : ((left < right) ? 1 : 0);\n      }\n    });\n\n    // for debugging\n    //Search.lastresults = results.slice();  // a copy\n    //console.info('search results:', Search.lastresults);\n\n    // print the results\n    var resultCount = results.length;\n    function displayNextItem() {\n      // results left, load the summary and display it\n      if (results.length) {\n        var item = results.pop();\n        var listItem = $('<li style=\"display:none\"></li>');\n        if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {\n          // dirhtml builder\n          var dirname = item[0] + '/';\n          if (dirname.match(/\\/index\\/$/)) {\n            dirname = dirname.substring(0, dirname.length-6);\n          } else if (dirname == 'index/') {\n            dirname = '';\n          }\n          listItem.append($('<a/>').attr('href',\n            DOCUMENTATION_OPTIONS.URL_ROOT + dirname +\n            highlightstring + item[2]).html(item[1]));\n        } else {\n          // normal html builders\n          listItem.append($('<a/>').attr('href',\n            item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +\n            highlightstring + item[2]).html(item[1]));\n        }\n        if (item[3]) {\n          listItem.append($('<span> (' + item[3] + ')</span>'));\n          Search.output.append(listItem);\n          listItem.slideDown(5, function() {\n            displayNextItem();\n          });\n        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {\n          var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;\n          $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),\n                  dataType: \"text\",\n                  complete: function(jqxhr, textstatus) {\n                    var data = jqxhr.responseText;\n                    if (data !== '' && data !== undefined) {\n                      listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));\n                    }\n                    Search.output.append(listItem);\n                    listItem.slideDown(5, function() {\n                      displayNextItem();\n                    });\n                  }});\n        } else {\n          // no source available, just display title\n          Search.output.append(listItem);\n          listItem.slideDown(5, function() {\n            displayNextItem();\n          });\n        }\n      }\n      // search finished, update title and status message\n      else {\n        Search.stopPulse();\n        Search.title.text(_('Search Results'));\n        if (!resultCount)\n          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\\'ve selected enough categories.'));\n        else\n            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));\n        Search.status.fadeIn(500);\n      }\n    }\n    displayNextItem();\n  },\n\n  /**\n   * search for object names\n   */\n  performObjectSearch : function(object, otherterms) {\n    var filenames = this._index.filenames;\n    var docnames = this._index.docnames;\n    var objects = this._index.objects;\n    var objnames = this._index.objnames;\n    var titles = this._index.titles;\n\n    var i;\n    var results = [];\n\n    for (var prefix in objects) {\n      for (var name in objects[prefix]) {\n        var fullname = (prefix ? prefix + '.' : '') + name;\n        if (fullname.toLowerCase().indexOf(object) > -1) {\n          var score = 0;\n          var parts = fullname.split('.');\n          // check for different match types: exact matches of full name or\n          // \"last name\" (i.e. last dotted part)\n          if (fullname == object || parts[parts.length - 1] == object) {\n            score += Scorer.objNameMatch;\n          // matches in last name\n          } else if (parts[parts.length - 1].indexOf(object) > -1) {\n            score += Scorer.objPartialMatch;\n          }\n          var match = objects[prefix][name];\n          var objname = objnames[match[1]][2];\n          var title = titles[match[0]];\n          // If more than one term searched for, we require other words to be\n          // found in the name/title/description\n          if (otherterms.length > 0) {\n            var haystack = (prefix + ' ' + name + ' ' +\n                            objname + ' ' + title).toLowerCase();\n            var allfound = true;\n            for (i = 0; i < otherterms.length; i++) {\n              if (haystack.indexOf(otherterms[i]) == -1) {\n                allfound = false;\n                break;\n              }\n            }\n            if (!allfound) {\n              continue;\n            }\n          }\n          var descr = objname + _(', in ') + title;\n\n          var anchor = match[3];\n          if (anchor === '')\n            anchor = fullname;\n          else if (anchor == '-')\n            anchor = objnames[match[1]][1] + '-' + fullname;\n          // add custom score for some objects according to scorer\n          if (Scorer.objPrio.hasOwnProperty(match[2])) {\n            score += Scorer.objPrio[match[2]];\n          } else {\n            score += Scorer.objPrioDefault;\n          }\n          results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);\n        }\n      }\n    }\n\n    return results;\n  },\n\n  /**\n   * search for full-text terms in the index\n   */\n  performTermsSearch : function(searchterms, excluded, terms, titleterms) {\n    var docnames = this._index.docnames;\n    var filenames = this._index.filenames;\n    var titles = this._index.titles;\n\n    var i, j, file;\n    var fileMap = {};\n    var scoreMap = {};\n    var results = [];\n\n    // perform the search on the required terms\n    for (i = 0; i < searchterms.length; i++) {\n      var word = searchterms[i];\n      var files = [];\n      var _o = [\n        {files: terms[word], score: Scorer.term},\n        {files: titleterms[word], score: Scorer.title}\n      ];\n\n      // no match but word was a required one\n      if ($u.every(_o, function(o){return o.files === undefined;})) {\n        break;\n      }\n      // found search word in contents\n      $u.each(_o, function(o) {\n        var _files = o.files;\n        if (_files === undefined)\n          return\n\n        if (_files.length === undefined)\n          _files = [_files];\n        files = files.concat(_files);\n\n        // set score for the word in each file to Scorer.term\n        for (j = 0; j < _files.length; j++) {\n          file = _files[j];\n          if (!(file in scoreMap))\n            scoreMap[file] = {}\n          scoreMap[file][word] = o.score;\n        }\n      });\n\n      // create the mapping\n      for (j = 0; j < files.length; j++) {\n        file = files[j];\n        if (file in fileMap)\n          fileMap[file].push(word);\n        else\n          fileMap[file] = [word];\n      }\n    }\n\n    // now check if the files don't contain excluded terms\n    for (file in fileMap) {\n      var valid = true;\n\n      // check if all requirements are matched\n      if (fileMap[file].length != searchterms.length)\n          continue;\n\n      // ensure that none of the excluded terms is in the search result\n      for (i = 0; i < excluded.length; i++) {\n        if (terms[excluded[i]] == file ||\n            titleterms[excluded[i]] == file ||\n            $u.contains(terms[excluded[i]] || [], file) ||\n            $u.contains(titleterms[excluded[i]] || [], file)) {\n          valid = false;\n          break;\n        }\n      }\n\n      // if we have still a valid result we can add it to the result list\n      if (valid) {\n        // select one (max) score for the file.\n        // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...\n        var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));\n        results.push([docnames[file], titles[file], '', null, score, filenames[file]]);\n      }\n    }\n    return results;\n  },\n\n  /**\n   * helper function to return a node containing the\n   * search summary for a given text. keywords is a list\n   * of stemmed words, hlwords is the list of normal, unstemmed\n   * words. the first one is used to find the occurrence, the\n   * latter for highlighting it.\n   */\n  makeSearchSummary : function(text, keywords, hlwords) {\n    var textLower = text.toLowerCase();\n    var start = 0;\n    $.each(keywords, function() {\n      var i = textLower.indexOf(this.toLowerCase());\n      if (i > -1)\n        start = i;\n    });\n    start = Math.max(start - 120, 0);\n    var excerpt = ((start > 0) ? '...' : '') +\n      $.trim(text.substr(start, 240)) +\n      ((start + 240 - text.length) ? '...' : '');\n    var rv = $('<div class=\"context\"></div>').text(excerpt);\n    $.each(hlwords, function() {\n      rv = rv.highlightText(this, 'highlighted');\n    });\n    return rv;\n  }\n};\n\n$(document).ready(function() {\n  Search.init();\n});"
  },
  {
    "path": "docs/_static/sphinx_highlight.js",
    "content": "/* Highlighting utilities for Sphinx HTML documentation. */\n\"use strict\";\n\nconst SPHINX_HIGHLIGHT_ENABLED = true\n\n/**\n * highlight a given string on a node by wrapping it in\n * span elements with the given class name.\n */\nconst _highlight = (node, addItems, text, className) => {\n  if (node.nodeType === Node.TEXT_NODE) {\n    const val = node.nodeValue;\n    const parent = node.parentNode;\n    const pos = val.toLowerCase().indexOf(text);\n    if (\n      pos >= 0 &&\n      !parent.classList.contains(className) &&\n      !parent.classList.contains(\"nohighlight\")\n    ) {\n      let span;\n\n      const closestNode = parent.closest(\"body, svg, foreignObject\");\n      const isInSVG = closestNode && closestNode.matches(\"svg\");\n      if (isInSVG) {\n        span = document.createElementNS(\"http://www.w3.org/2000/svg\", \"tspan\");\n      } else {\n        span = document.createElement(\"span\");\n        span.classList.add(className);\n      }\n\n      span.appendChild(document.createTextNode(val.substr(pos, text.length)));\n      const rest = document.createTextNode(val.substr(pos + text.length));\n      parent.insertBefore(\n        span,\n        parent.insertBefore(\n          rest,\n          node.nextSibling\n        )\n      );\n      node.nodeValue = val.substr(0, pos);\n      /* There may be more occurrences of search term in this node. So call this\n       * function recursively on the remaining fragment.\n       */\n      _highlight(rest, addItems, text, className);\n\n      if (isInSVG) {\n        const rect = document.createElementNS(\n          \"http://www.w3.org/2000/svg\",\n          \"rect\"\n        );\n        const bbox = parent.getBBox();\n        rect.x.baseVal.value = bbox.x;\n        rect.y.baseVal.value = bbox.y;\n        rect.width.baseVal.value = bbox.width;\n        rect.height.baseVal.value = bbox.height;\n        rect.setAttribute(\"class\", className);\n        addItems.push({ parent: parent, target: rect });\n      }\n    }\n  } else if (node.matches && !node.matches(\"button, select, textarea\")) {\n    node.childNodes.forEach((el) => _highlight(el, addItems, text, className));\n  }\n};\nconst _highlightText = (thisNode, text, className) => {\n  let addItems = [];\n  _highlight(thisNode, addItems, text, className);\n  addItems.forEach((obj) =>\n    obj.parent.insertAdjacentElement(\"beforebegin\", obj.target)\n  );\n};\n\n/**\n * Small JavaScript module for the documentation.\n */\nconst SphinxHighlight = {\n\n  /**\n   * highlight the search words provided in localstorage in the text\n   */\n  highlightSearchWords: () => {\n    if (!SPHINX_HIGHLIGHT_ENABLED) return;  // bail if no highlight\n\n    // get and clear terms from localstorage\n    const url = new URL(window.location);\n    const highlight =\n        localStorage.getItem(\"sphinx_highlight_terms\")\n        || url.searchParams.get(\"highlight\")\n        || \"\";\n    localStorage.removeItem(\"sphinx_highlight_terms\")\n    url.searchParams.delete(\"highlight\");\n    window.history.replaceState({}, \"\", url);\n\n    // get individual terms from highlight string\n    const terms = highlight.toLowerCase().split(/\\s+/).filter(x => x);\n    if (terms.length === 0) return; // nothing to do\n\n    // There should never be more than one element matching \"div.body\"\n    const divBody = document.querySelectorAll(\"div.body\");\n    const body = divBody.length ? divBody[0] : document.querySelector(\"body\");\n    window.setTimeout(() => {\n      terms.forEach((term) => _highlightText(body, term, \"highlighted\"));\n    }, 10);\n\n    const searchBox = document.getElementById(\"searchbox\");\n    if (searchBox === null) return;\n    searchBox.appendChild(\n      document\n        .createRange()\n        .createContextualFragment(\n          '<p class=\"highlight-link\">' +\n            '<a href=\"javascript:SphinxHighlight.hideSearchWords()\">' +\n            _(\"Hide Search Matches\") +\n            \"</a></p>\"\n        )\n    );\n  },\n\n  /**\n   * helper function to hide the search marks again\n   */\n  hideSearchWords: () => {\n    document\n      .querySelectorAll(\"#searchbox .highlight-link\")\n      .forEach((el) => el.remove());\n    document\n      .querySelectorAll(\"span.highlighted\")\n      .forEach((el) => el.classList.remove(\"highlighted\"));\n    localStorage.removeItem(\"sphinx_highlight_terms\")\n  },\n\n  initEscapeListener: () => {\n    // only install a listener if it is really needed\n    if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return;\n\n    document.addEventListener(\"keydown\", (event) => {\n      // bail for input elements\n      if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;\n      // bail with special keys\n      if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;\n      if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === \"Escape\")) {\n        SphinxHighlight.hideSearchWords();\n        event.preventDefault();\n      }\n    });\n  },\n};\n\n_ready(() => {\n  /* Do not call highlightSearchWords() when we are on the search page.\n   * It will highlight words from the *previous* search query.\n   */\n  if (typeof Search === \"undefined\") SphinxHighlight.highlightSearchWords();\n  SphinxHighlight.initEscapeListener();\n});\n"
  },
  {
    "path": "docs/_static/sphinxdoc.css",
    "content": "/*\n * sphinxdoc.css_t\n * ~~~~~~~~~~~~~~~\n *\n * Sphinx stylesheet -- sphinxdoc theme.  Originally created by\n * Armin Ronacher for Werkzeug.\n *\n * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n@import url(\"basic.css\");\n\n/* -- page layout ----------------------------------------------------------- */\n\nbody {\n    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',\n                 'Verdana', sans-serif;\n    font-size: 14px;\n    letter-spacing: -0.01em;\n    line-height: 150%;\n    text-align: center;\n    background-color: #BFD1D4;\n    color: black;\n    padding: 0;\n    border: 1px solid #aaa;\n\n    margin: 0px 80px 0px 80px;\n    min-width: 740px;\n}\n\ndiv.document {\n    background-color: white;\n    text-align: left;\n    background-image: url(contents.png);\n    background-repeat: repeat-x;\n}\n\ndiv.bodywrapper {\n    margin: 0 calc(230px + 10px) 0 0;\n    border-right: 1px solid #ccc;\n}\n\ndiv.body {\n    margin: 0;\n    padding: 0.5em 20px 20px 20px;\n}\n\ndiv.related {\n    font-size: 1em;\n}\n\ndiv.related ul {\n    background-image: url(navigation.png);\n    height: 2em;\n    border-top: 1px solid #ddd;\n    border-bottom: 1px solid #ddd;\n}\n\ndiv.related ul li {\n    margin: 0;\n    padding: 0;\n    height: 2em;\n    float: left;\n}\n\ndiv.related ul li.right {\n    float: right;\n    margin-right: 5px;\n}\n\ndiv.related ul li a {\n    margin: 0;\n    padding: 0 5px 0 5px;\n    line-height: 1.75em;\n    color: #EE9816;\n}\n\ndiv.related ul li a:hover {\n    color: #3CA8E7;\n}\n\ndiv.sphinxsidebarwrapper {\n    padding: 0;\n}\n\ndiv.sphinxsidebar {\n    margin: 0;\n    padding: 0.5em 15px 15px 0;\n    width: calc(230px - 20px);\n    float: right;\n    font-size: 1em;\n    text-align: left;\n}\n\ndiv.sphinxsidebar h3, div.sphinxsidebar h4 {\n    margin: 1em 0 0.5em 0;\n    font-size: 1em;\n    padding: 0.1em 0 0.1em 0.5em;\n    color: white;\n    border: 1px solid #86989B;\n    background-color: #AFC1C4;\n}\n\ndiv.sphinxsidebar h3 a {\n    color: white;\n}\n\ndiv.sphinxsidebar ul {\n    padding-left: 1.5em;\n    margin-top: 7px;\n    padding: 0;\n    line-height: 130%;\n}\n\ndiv.sphinxsidebar ul ul {\n    margin-left: 20px;\n}\n\ndiv.footer {\n    background-color: #E3EFF1;\n    color: #86989B;\n    padding: 3px 8px 3px 0;\n    clear: both;\n    font-size: 0.8em;\n    text-align: right;\n}\n\ndiv.footer a {\n    color: #86989B;\n    text-decoration: underline;\n}\n\n/* -- body styles ----------------------------------------------------------- */\n\np {    \n    margin: 0.8em 0 0.5em 0;\n}\n\na {\n    color: #CA7900;\n    text-decoration: none;\n}\n\na:hover {\n    color: #2491CF;\n}\n\ndiv.body a {\n    text-decoration: underline;\n}\n\nh1 {\n    margin: 0;\n    padding: 0.7em 0 0.3em 0;\n    font-size: 1.5em;\n    color: #11557C;\n}\n\nh2 {\n    margin: 1.3em 0 0.2em 0;\n    font-size: 1.35em;\n    padding: 0;\n}\n\nh3 {\n    margin: 1em 0 -0.3em 0;\n    font-size: 1.2em;\n}\n\ndiv.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {\n    color: black!important;\n}\n\nh1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {\n    display: none;\n    margin: 0 0 0 0.3em;\n    padding: 0 0.2em 0 0.2em;\n    color: #aaa!important;\n}\n\nh1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,\nh5:hover a.anchor, h6:hover a.anchor {\n    display: inline;\n}\n\nh1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,\nh5 a.anchor:hover, h6 a.anchor:hover {\n    color: #777;\n    background-color: #eee;\n}\n\na.headerlink {\n    color: #c60f0f!important;\n    font-size: 1em;\n    margin-left: 6px;\n    padding: 0 4px 0 4px;\n    text-decoration: none!important;\n}\n\na.headerlink:hover {\n    background-color: #ccc;\n    color: white!important;\n}\n\ncite, code, code {\n    font-family: 'Consolas', 'Deja Vu Sans Mono',\n                 'Bitstream Vera Sans Mono', monospace;\n    font-size: 0.95em;\n    letter-spacing: 0.01em;\n}\n\ncode {\n    background-color: #f2f2f2;\n    border-bottom: 1px solid #ddd;\n    color: #333;\n}\n\ncode.descname, code.descclassname, code.xref {\n    border: 0;\n}\n\nhr {\n    border: 1px solid #abc;\n    margin: 2em;\n}\n\na code {\n    border: 0;\n    color: #CA7900;\n}\n\na code:hover {\n    color: #2491CF;\n}\n\npre {\n    font-family: 'Consolas', 'Deja Vu Sans Mono',\n                 'Bitstream Vera Sans Mono', monospace;\n    font-size: 0.95em;\n    letter-spacing: 0.015em;\n    line-height: 120%;\n    padding: 0.5em;\n    border: 1px solid #ccc;\n    background-color: #f8f8f8;\n}\n\npre a {\n    color: inherit;\n    text-decoration: underline;\n}\n\ntd.linenos pre {\n    padding: 0.5em 0;\n}\n\ndiv.quotebar {\n    background-color: #f8f8f8;\n    max-width: 250px;\n    float: right;\n    padding: 2px 7px;\n    border: 1px solid #ccc;\n}\n\ndiv.topic {\n    background-color: #f8f8f8;\n}\n\ntable {\n    border-collapse: collapse;\n    margin: 0 -0.5em 0 -0.5em;\n}\n\ntable td, table th {\n    padding: 0.2em 0.5em 0.2em 0.5em;\n}\n\ndiv.admonition, div.warning {\n    font-size: 0.9em;\n    margin: 1em 0 1em 0;\n    border: 1px solid #86989B;\n    background-color: #f7f7f7;\n    padding: 0;\n}\n\ndiv.admonition p, div.warning p {\n    margin: 0.5em 1em 0.5em 1em;\n    padding: 0;\n}\n\ndiv.admonition pre, div.warning pre {\n    margin: 0.4em 1em 0.4em 1em;\n}\n\ndiv.admonition p.admonition-title,\ndiv.warning p.admonition-title {\n    margin: 0;\n    padding: 0.1em 0 0.1em 0.5em;\n    color: white;\n    border-bottom: 1px solid #86989B;\n    font-weight: bold;\n    background-color: #AFC1C4;\n}\n\ndiv.warning {\n    border: 1px solid #940000;\n}\n\ndiv.warning p.admonition-title {\n    background-color: #CF0000;\n    border-bottom-color: #940000;\n}\n\ndiv.admonition ul, div.admonition ol,\ndiv.warning ul, div.warning ol {\n    margin: 0.1em 0.5em 0.5em 3em;\n    padding: 0;\n}\n\ndiv.versioninfo {\n    margin: 1em 0 0 0;\n    border: 1px solid #ccc;\n    background-color: #DDEAF0;\n    padding: 8px;\n    line-height: 1.3em;\n    font-size: 0.9em;\n}\n\n.viewcode-back {\n    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',\n                 'Verdana', sans-serif;\n}\n\ndiv.viewcode-block:target {\n    background-color: #f4debf;\n    border-top: 1px solid #ac9;\n    border-bottom: 1px solid #ac9;\n}\n\ndiv.code-block-caption {\n    background-color: #ddd;\n    color: #222;\n    border: 1px solid #ccc;\n}"
  },
  {
    "path": "docs/_static/underscore-1.13.1.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define('underscore', factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () {\n    var current = global._;\n    var exports = global._ = factory();\n    exports.noConflict = function () { global._ = current; return exports; };\n  }()));\n}(this, (function () {\n  //     Underscore.js 1.13.1\n  //     https://underscorejs.org\n  //     (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors\n  //     Underscore may be freely distributed under the MIT license.\n\n  // Current version.\n  var VERSION = '1.13.1';\n\n  // Establish the root object, `window` (`self`) in the browser, `global`\n  // on the server, or `this` in some virtual machines. We use `self`\n  // instead of `window` for `WebWorker` support.\n  var root = typeof self == 'object' && self.self === self && self ||\n            typeof global == 'object' && global.global === global && global ||\n            Function('return this')() ||\n            {};\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype;\n  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var push = ArrayProto.push,\n      slice = ArrayProto.slice,\n      toString = ObjProto.toString,\n      hasOwnProperty = ObjProto.hasOwnProperty;\n\n  // Modern feature detection.\n  var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',\n      supportsDataView = typeof DataView !== 'undefined';\n\n  // All **ECMAScript 5+** native function implementations that we hope to use\n  // are declared here.\n  var nativeIsArray = Array.isArray,\n      nativeKeys = Object.keys,\n      nativeCreate = Object.create,\n      nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;\n\n  // Create references to these builtin functions because we override them.\n  var _isNaN = isNaN,\n      _isFinite = isFinite;\n\n  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\n  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');\n  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',\n    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];\n\n  // The largest integer that can be represented exactly.\n  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;\n\n  // Some functions take a variable number of arguments, or a few expected\n  // arguments at the beginning and then a variable number of values to operate\n  // on. This helper accumulates all remaining arguments past the function’s\n  // argument length (or an explicit `startIndex`), into an array that becomes\n  // the last argument. Similar to ES6’s \"rest parameter\".\n  function restArguments(func, startIndex) {\n    startIndex = startIndex == null ? func.length - 1 : +startIndex;\n    return function() {\n      var length = Math.max(arguments.length - startIndex, 0),\n          rest = Array(length),\n          index = 0;\n      for (; index < length; index++) {\n        rest[index] = arguments[index + startIndex];\n      }\n      switch (startIndex) {\n        case 0: return func.call(this, rest);\n        case 1: return func.call(this, arguments[0], rest);\n        case 2: return func.call(this, arguments[0], arguments[1], rest);\n      }\n      var args = Array(startIndex + 1);\n      for (index = 0; index < startIndex; index++) {\n        args[index] = arguments[index];\n      }\n      args[startIndex] = rest;\n      return func.apply(this, args);\n    };\n  }\n\n  // Is a given variable an object?\n  function isObject(obj) {\n    var type = typeof obj;\n    return type === 'function' || type === 'object' && !!obj;\n  }\n\n  // Is a given value equal to null?\n  function isNull(obj) {\n    return obj === null;\n  }\n\n  // Is a given variable undefined?\n  function isUndefined(obj) {\n    return obj === void 0;\n  }\n\n  // Is a given value a boolean?\n  function isBoolean(obj) {\n    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';\n  }\n\n  // Is a given value a DOM element?\n  function isElement(obj) {\n    return !!(obj && obj.nodeType === 1);\n  }\n\n  // Internal function for creating a `toString`-based type tester.\n  function tagTester(name) {\n    var tag = '[object ' + name + ']';\n    return function(obj) {\n      return toString.call(obj) === tag;\n    };\n  }\n\n  var isString = tagTester('String');\n\n  var isNumber = tagTester('Number');\n\n  var isDate = tagTester('Date');\n\n  var isRegExp = tagTester('RegExp');\n\n  var isError = tagTester('Error');\n\n  var isSymbol = tagTester('Symbol');\n\n  var isArrayBuffer = tagTester('ArrayBuffer');\n\n  var isFunction = tagTester('Function');\n\n  // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old\n  // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).\n  var nodelist = root.document && root.document.childNodes;\n  if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {\n    isFunction = function(obj) {\n      return typeof obj == 'function' || false;\n    };\n  }\n\n  var isFunction$1 = isFunction;\n\n  var hasObjectTag = tagTester('Object');\n\n  // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.\n  // In IE 11, the most common among them, this problem also applies to\n  // `Map`, `WeakMap` and `Set`.\n  var hasStringTagBug = (\n        supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))\n      ),\n      isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));\n\n  var isDataView = tagTester('DataView');\n\n  // In IE 10 - Edge 13, we need a different heuristic\n  // to determine whether an object is a `DataView`.\n  function ie10IsDataView(obj) {\n    return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);\n  }\n\n  var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView);\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native `Array.isArray`.\n  var isArray = nativeIsArray || tagTester('Array');\n\n  // Internal function to check whether `key` is an own property name of `obj`.\n  function has$1(obj, key) {\n    return obj != null && hasOwnProperty.call(obj, key);\n  }\n\n  var isArguments = tagTester('Arguments');\n\n  // Define a fallback version of the method in browsers (ahem, IE < 9), where\n  // there isn't any inspectable \"Arguments\" type.\n  (function() {\n    if (!isArguments(arguments)) {\n      isArguments = function(obj) {\n        return has$1(obj, 'callee');\n      };\n    }\n  }());\n\n  var isArguments$1 = isArguments;\n\n  // Is a given object a finite number?\n  function isFinite$1(obj) {\n    return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));\n  }\n\n  // Is the given value `NaN`?\n  function isNaN$1(obj) {\n    return isNumber(obj) && _isNaN(obj);\n  }\n\n  // Predicate-generating function. Often useful outside of Underscore.\n  function constant(value) {\n    return function() {\n      return value;\n    };\n  }\n\n  // Common internal logic for `isArrayLike` and `isBufferLike`.\n  function createSizePropertyCheck(getSizeProperty) {\n    return function(collection) {\n      var sizeProperty = getSizeProperty(collection);\n      return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;\n    }\n  }\n\n  // Internal helper to generate a function to obtain property `key` from `obj`.\n  function shallowProperty(key) {\n    return function(obj) {\n      return obj == null ? void 0 : obj[key];\n    };\n  }\n\n  // Internal helper to obtain the `byteLength` property of an object.\n  var getByteLength = shallowProperty('byteLength');\n\n  // Internal helper to determine whether we should spend extensive checks against\n  // `ArrayBuffer` et al.\n  var isBufferLike = createSizePropertyCheck(getByteLength);\n\n  // Is a given value a typed array?\n  var typedArrayPattern = /\\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\\]/;\n  function isTypedArray(obj) {\n    // `ArrayBuffer.isView` is the most future-proof, so use it when available.\n    // Otherwise, fall back on the above regular expression.\n    return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) :\n                  isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));\n  }\n\n  var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false);\n\n  // Internal helper to obtain the `length` property of an object.\n  var getLength = shallowProperty('length');\n\n  // Internal helper to create a simple lookup structure.\n  // `collectNonEnumProps` used to depend on `_.contains`, but this led to\n  // circular imports. `emulatedSet` is a one-off solution that only works for\n  // arrays of strings.\n  function emulatedSet(keys) {\n    var hash = {};\n    for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;\n    return {\n      contains: function(key) { return hash[key]; },\n      push: function(key) {\n        hash[key] = true;\n        return keys.push(key);\n      }\n    };\n  }\n\n  // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't\n  // be iterated by `for key in ...` and thus missed. Extends `keys` in place if\n  // needed.\n  function collectNonEnumProps(obj, keys) {\n    keys = emulatedSet(keys);\n    var nonEnumIdx = nonEnumerableProps.length;\n    var constructor = obj.constructor;\n    var proto = isFunction$1(constructor) && constructor.prototype || ObjProto;\n\n    // Constructor is a special case.\n    var prop = 'constructor';\n    if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop);\n\n    while (nonEnumIdx--) {\n      prop = nonEnumerableProps[nonEnumIdx];\n      if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {\n        keys.push(prop);\n      }\n    }\n  }\n\n  // Retrieve the names of an object's own properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`.\n  function keys(obj) {\n    if (!isObject(obj)) return [];\n    if (nativeKeys) return nativeKeys(obj);\n    var keys = [];\n    for (var key in obj) if (has$1(obj, key)) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  }\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  function isEmpty(obj) {\n    if (obj == null) return true;\n    // Skip the more expensive `toString`-based type checks if `obj` has no\n    // `.length`.\n    var length = getLength(obj);\n    if (typeof length == 'number' && (\n      isArray(obj) || isString(obj) || isArguments$1(obj)\n    )) return length === 0;\n    return getLength(keys(obj)) === 0;\n  }\n\n  // Returns whether an object has a given set of `key:value` pairs.\n  function isMatch(object, attrs) {\n    var _keys = keys(attrs), length = _keys.length;\n    if (object == null) return !length;\n    var obj = Object(object);\n    for (var i = 0; i < length; i++) {\n      var key = _keys[i];\n      if (attrs[key] !== obj[key] || !(key in obj)) return false;\n    }\n    return true;\n  }\n\n  // If Underscore is called as a function, it returns a wrapped object that can\n  // be used OO-style. This wrapper holds altered versions of all functions added\n  // through `_.mixin`. Wrapped objects may be chained.\n  function _$1(obj) {\n    if (obj instanceof _$1) return obj;\n    if (!(this instanceof _$1)) return new _$1(obj);\n    this._wrapped = obj;\n  }\n\n  _$1.VERSION = VERSION;\n\n  // Extracts the result from a wrapped and chained object.\n  _$1.prototype.value = function() {\n    return this._wrapped;\n  };\n\n  // Provide unwrapping proxies for some methods used in engine operations\n  // such as arithmetic and JSON stringification.\n  _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value;\n\n  _$1.prototype.toString = function() {\n    return String(this._wrapped);\n  };\n\n  // Internal function to wrap or shallow-copy an ArrayBuffer,\n  // typed array or DataView to a new view, reusing the buffer.\n  function toBufferView(bufferSource) {\n    return new Uint8Array(\n      bufferSource.buffer || bufferSource,\n      bufferSource.byteOffset || 0,\n      getByteLength(bufferSource)\n    );\n  }\n\n  // We use this string twice, so give it a name for minification.\n  var tagDataView = '[object DataView]';\n\n  // Internal recursive comparison function for `_.isEqual`.\n  function eq(a, b, aStack, bStack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) return a !== 0 || 1 / a === 1 / b;\n    // `null` or `undefined` only equal to itself (strict comparison).\n    if (a == null || b == null) return false;\n    // `NaN`s are equivalent, but non-reflexive.\n    if (a !== a) return b !== b;\n    // Exhaust primitive checks\n    var type = typeof a;\n    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;\n    return deepEq(a, b, aStack, bStack);\n  }\n\n  // Internal recursive comparison function for `_.isEqual`.\n  function deepEq(a, b, aStack, bStack) {\n    // Unwrap any wrapped objects.\n    if (a instanceof _$1) a = a._wrapped;\n    if (b instanceof _$1) b = b._wrapped;\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className !== toString.call(b)) return false;\n    // Work around a bug in IE 10 - Edge 13.\n    if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {\n      if (!isDataView$1(b)) return false;\n      className = tagDataView;\n    }\n    switch (className) {\n      // These types are compared by value.\n      case '[object RegExp]':\n        // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return '' + a === '' + b;\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive.\n        // Object(NaN) is equivalent to NaN.\n        if (+a !== +a) return +b !== +b;\n        // An `egal` comparison is performed for other numeric values.\n        return +a === 0 ? 1 / +a === 1 / b : +a === +b;\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a === +b;\n      case '[object Symbol]':\n        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);\n      case '[object ArrayBuffer]':\n      case tagDataView:\n        // Coerce to typed array so we can fall through.\n        return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);\n    }\n\n    var areArrays = className === '[object Array]';\n    if (!areArrays && isTypedArray$1(a)) {\n        var byteLength = getByteLength(a);\n        if (byteLength !== getByteLength(b)) return false;\n        if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;\n        areArrays = true;\n    }\n    if (!areArrays) {\n      if (typeof a != 'object' || typeof b != 'object') return false;\n\n      // Objects with different constructors are not equivalent, but `Object`s or `Array`s\n      // from different frames are.\n      var aCtor = a.constructor, bCtor = b.constructor;\n      if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor &&\n                               isFunction$1(bCtor) && bCtor instanceof bCtor)\n                          && ('constructor' in a && 'constructor' in b)) {\n        return false;\n      }\n    }\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n\n    // Initializing stack of traversed objects.\n    // It's done here since we only need them for objects and arrays comparison.\n    aStack = aStack || [];\n    bStack = bStack || [];\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] === a) return bStack[length] === b;\n    }\n\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n\n    // Recursively compare objects and arrays.\n    if (areArrays) {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      length = a.length;\n      if (length !== b.length) return false;\n      // Deep compare the contents, ignoring non-numeric properties.\n      while (length--) {\n        if (!eq(a[length], b[length], aStack, bStack)) return false;\n      }\n    } else {\n      // Deep compare objects.\n      var _keys = keys(a), key;\n      length = _keys.length;\n      // Ensure that both objects contain the same number of properties before comparing deep equality.\n      if (keys(b).length !== length) return false;\n      while (length--) {\n        // Deep compare each member\n        key = _keys[length];\n        if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n    return true;\n  }\n\n  // Perform a deep comparison to check if two objects are equal.\n  function isEqual(a, b) {\n    return eq(a, b);\n  }\n\n  // Retrieve all the enumerable property names of an object.\n  function allKeys(obj) {\n    if (!isObject(obj)) return [];\n    var keys = [];\n    for (var key in obj) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  }\n\n  // Since the regular `Object.prototype.toString` type tests don't work for\n  // some types in IE 11, we use a fingerprinting heuristic instead, based\n  // on the methods. It's not great, but it's the best we got.\n  // The fingerprint method lists are defined below.\n  function ie11fingerprint(methods) {\n    var length = getLength(methods);\n    return function(obj) {\n      if (obj == null) return false;\n      // `Map`, `WeakMap` and `Set` have no enumerable keys.\n      var keys = allKeys(obj);\n      if (getLength(keys)) return false;\n      for (var i = 0; i < length; i++) {\n        if (!isFunction$1(obj[methods[i]])) return false;\n      }\n      // If we are testing against `WeakMap`, we need to ensure that\n      // `obj` doesn't have a `forEach` method in order to distinguish\n      // it from a regular `Map`.\n      return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);\n    };\n  }\n\n  // In the interest of compact minification, we write\n  // each string in the fingerprints only once.\n  var forEachName = 'forEach',\n      hasName = 'has',\n      commonInit = ['clear', 'delete'],\n      mapTail = ['get', hasName, 'set'];\n\n  // `Map`, `WeakMap` and `Set` each have slightly different\n  // combinations of the above sublists.\n  var mapMethods = commonInit.concat(forEachName, mapTail),\n      weakMapMethods = commonInit.concat(mapTail),\n      setMethods = ['add'].concat(commonInit, forEachName, hasName);\n\n  var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');\n\n  var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');\n\n  var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');\n\n  var isWeakSet = tagTester('WeakSet');\n\n  // Retrieve the values of an object's properties.\n  function values(obj) {\n    var _keys = keys(obj);\n    var length = _keys.length;\n    var values = Array(length);\n    for (var i = 0; i < length; i++) {\n      values[i] = obj[_keys[i]];\n    }\n    return values;\n  }\n\n  // Convert an object into a list of `[key, value]` pairs.\n  // The opposite of `_.object` with one argument.\n  function pairs(obj) {\n    var _keys = keys(obj);\n    var length = _keys.length;\n    var pairs = Array(length);\n    for (var i = 0; i < length; i++) {\n      pairs[i] = [_keys[i], obj[_keys[i]]];\n    }\n    return pairs;\n  }\n\n  // Invert the keys and values of an object. The values must be serializable.\n  function invert(obj) {\n    var result = {};\n    var _keys = keys(obj);\n    for (var i = 0, length = _keys.length; i < length; i++) {\n      result[obj[_keys[i]]] = _keys[i];\n    }\n    return result;\n  }\n\n  // Return a sorted list of the function names available on the object.\n  function functions(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (isFunction$1(obj[key])) names.push(key);\n    }\n    return names.sort();\n  }\n\n  // An internal function for creating assigner functions.\n  function createAssigner(keysFunc, defaults) {\n    return function(obj) {\n      var length = arguments.length;\n      if (defaults) obj = Object(obj);\n      if (length < 2 || obj == null) return obj;\n      for (var index = 1; index < length; index++) {\n        var source = arguments[index],\n            keys = keysFunc(source),\n            l = keys.length;\n        for (var i = 0; i < l; i++) {\n          var key = keys[i];\n          if (!defaults || obj[key] === void 0) obj[key] = source[key];\n        }\n      }\n      return obj;\n    };\n  }\n\n  // Extend a given object with all the properties in passed-in object(s).\n  var extend = createAssigner(allKeys);\n\n  // Assigns a given object with all the own properties in the passed-in\n  // object(s).\n  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n  var extendOwn = createAssigner(keys);\n\n  // Fill in a given object with default properties.\n  var defaults = createAssigner(allKeys, true);\n\n  // Create a naked function reference for surrogate-prototype-swapping.\n  function ctor() {\n    return function(){};\n  }\n\n  // An internal function for creating a new object that inherits from another.\n  function baseCreate(prototype) {\n    if (!isObject(prototype)) return {};\n    if (nativeCreate) return nativeCreate(prototype);\n    var Ctor = ctor();\n    Ctor.prototype = prototype;\n    var result = new Ctor;\n    Ctor.prototype = null;\n    return result;\n  }\n\n  // Creates an object that inherits from the given prototype object.\n  // If additional properties are provided then they will be added to the\n  // created object.\n  function create(prototype, props) {\n    var result = baseCreate(prototype);\n    if (props) extendOwn(result, props);\n    return result;\n  }\n\n  // Create a (shallow-cloned) duplicate of an object.\n  function clone(obj) {\n    if (!isObject(obj)) return obj;\n    return isArray(obj) ? obj.slice() : extend({}, obj);\n  }\n\n  // Invokes `interceptor` with the `obj` and then returns `obj`.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  function tap(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  }\n\n  // Normalize a (deep) property `path` to array.\n  // Like `_.iteratee`, this function can be customized.\n  function toPath$1(path) {\n    return isArray(path) ? path : [path];\n  }\n  _$1.toPath = toPath$1;\n\n  // Internal wrapper for `_.toPath` to enable minification.\n  // Similar to `cb` for `_.iteratee`.\n  function toPath(path) {\n    return _$1.toPath(path);\n  }\n\n  // Internal function to obtain a nested property in `obj` along `path`.\n  function deepGet(obj, path) {\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      if (obj == null) return void 0;\n      obj = obj[path[i]];\n    }\n    return length ? obj : void 0;\n  }\n\n  // Get the value of the (deep) property on `path` from `object`.\n  // If any property in `path` does not exist or if the value is\n  // `undefined`, return `defaultValue` instead.\n  // The `path` is normalized through `_.toPath`.\n  function get(object, path, defaultValue) {\n    var value = deepGet(object, toPath(path));\n    return isUndefined(value) ? defaultValue : value;\n  }\n\n  // Shortcut function for checking if an object has a given property directly on\n  // itself (in other words, not on a prototype). Unlike the internal `has`\n  // function, this public version can also traverse nested properties.\n  function has(obj, path) {\n    path = toPath(path);\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      var key = path[i];\n      if (!has$1(obj, key)) return false;\n      obj = obj[key];\n    }\n    return !!length;\n  }\n\n  // Keep the identity function around for default iteratees.\n  function identity(value) {\n    return value;\n  }\n\n  // Returns a predicate for checking whether an object has a given set of\n  // `key:value` pairs.\n  function matcher(attrs) {\n    attrs = extendOwn({}, attrs);\n    return function(obj) {\n      return isMatch(obj, attrs);\n    };\n  }\n\n  // Creates a function that, when passed an object, will traverse that object’s\n  // properties down the given `path`, specified as an array of keys or indices.\n  function property(path) {\n    path = toPath(path);\n    return function(obj) {\n      return deepGet(obj, path);\n    };\n  }\n\n  // Internal function that returns an efficient (for current engines) version\n  // of the passed-in callback, to be repeatedly applied in other Underscore\n  // functions.\n  function optimizeCb(func, context, argCount) {\n    if (context === void 0) return func;\n    switch (argCount == null ? 3 : argCount) {\n      case 1: return function(value) {\n        return func.call(context, value);\n      };\n      // The 2-argument case is omitted because we’re not using it.\n      case 3: return function(value, index, collection) {\n        return func.call(context, value, index, collection);\n      };\n      case 4: return function(accumulator, value, index, collection) {\n        return func.call(context, accumulator, value, index, collection);\n      };\n    }\n    return function() {\n      return func.apply(context, arguments);\n    };\n  }\n\n  // An internal function to generate callbacks that can be applied to each\n  // element in a collection, returning the desired result — either `_.identity`,\n  // an arbitrary callback, a property matcher, or a property accessor.\n  function baseIteratee(value, context, argCount) {\n    if (value == null) return identity;\n    if (isFunction$1(value)) return optimizeCb(value, context, argCount);\n    if (isObject(value) && !isArray(value)) return matcher(value);\n    return property(value);\n  }\n\n  // External wrapper for our callback generator. Users may customize\n  // `_.iteratee` if they want additional predicate/iteratee shorthand styles.\n  // This abstraction hides the internal-only `argCount` argument.\n  function iteratee(value, context) {\n    return baseIteratee(value, context, Infinity);\n  }\n  _$1.iteratee = iteratee;\n\n  // The function we call internally to generate a callback. It invokes\n  // `_.iteratee` if overridden, otherwise `baseIteratee`.\n  function cb(value, context, argCount) {\n    if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context);\n    return baseIteratee(value, context, argCount);\n  }\n\n  // Returns the results of applying the `iteratee` to each element of `obj`.\n  // In contrast to `_.map` it returns an object.\n  function mapObject(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var _keys = keys(obj),\n        length = _keys.length,\n        results = {};\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys[index];\n      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  }\n\n  // Predicate-generating function. Often useful outside of Underscore.\n  function noop(){}\n\n  // Generates a function for a given object that returns a given property.\n  function propertyOf(obj) {\n    if (obj == null) return noop;\n    return function(path) {\n      return get(obj, path);\n    };\n  }\n\n  // Run a function **n** times.\n  function times(n, iteratee, context) {\n    var accum = Array(Math.max(0, n));\n    iteratee = optimizeCb(iteratee, context, 1);\n    for (var i = 0; i < n; i++) accum[i] = iteratee(i);\n    return accum;\n  }\n\n  // Return a random integer between `min` and `max` (inclusive).\n  function random(min, max) {\n    if (max == null) {\n      max = min;\n      min = 0;\n    }\n    return min + Math.floor(Math.random() * (max - min + 1));\n  }\n\n  // A (possibly faster) way to get the current timestamp as an integer.\n  var now = Date.now || function() {\n    return new Date().getTime();\n  };\n\n  // Internal helper to generate functions for escaping and unescaping strings\n  // to/from HTML interpolation.\n  function createEscaper(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  }\n\n  // Internal list of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n\n  // Function for escaping strings to HTML interpolation.\n  var _escape = createEscaper(escapeMap);\n\n  // Internal list of HTML entities for unescaping.\n  var unescapeMap = invert(escapeMap);\n\n  // Function for unescaping strings from HTML interpolation.\n  var _unescape = createEscaper(unescapeMap);\n\n  // By default, Underscore uses ERB-style template delimiters. Change the\n  // following template settings to use alternative delimiters.\n  var templateSettings = _$1.templateSettings = {\n    evaluate: /<%([\\s\\S]+?)%>/g,\n    interpolate: /<%=([\\s\\S]+?)%>/g,\n    escape: /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `_.templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /(.)^/;\n\n  // Certain characters need to be escaped so that they can be put into a\n  // string literal.\n  var escapes = {\n    \"'\": \"'\",\n    '\\\\': '\\\\',\n    '\\r': 'r',\n    '\\n': 'n',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  var escapeRegExp = /\\\\|'|\\r|\\n|\\u2028|\\u2029/g;\n\n  function escapeChar(match) {\n    return '\\\\' + escapes[match];\n  }\n\n  // In order to prevent third-party code injection through\n  // `_.templateSettings.variable`, we test it against the following regular\n  // expression. It is intentionally a bit more liberal than just matching valid\n  // identifiers, but still prevents possible loopholes through defaults or\n  // destructuring assignment.\n  var bareIdentifier = /^\\s*(\\w|\\$)+\\s*$/;\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  // NB: `oldSettings` only exists for backwards compatibility.\n  function template(text, settings, oldSettings) {\n    if (!settings && oldSettings) settings = oldSettings;\n    settings = defaults({}, settings, _$1.templateSettings);\n\n    // Combine delimiters into one regular expression via alternation.\n    var matcher = RegExp([\n      (settings.escape || noMatch).source,\n      (settings.interpolate || noMatch).source,\n      (settings.evaluate || noMatch).source\n    ].join('|') + '|$', 'g');\n\n    // Compile the template source, escaping string literals appropriately.\n    var index = 0;\n    var source = \"__p+='\";\n    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\n      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);\n      index = offset + match.length;\n\n      if (escape) {\n        source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\n      } else if (interpolate) {\n        source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\n      } else if (evaluate) {\n        source += \"';\\n\" + evaluate + \"\\n__p+='\";\n      }\n\n      // Adobe VMs need the match returned to produce the correct offset.\n      return match;\n    });\n    source += \"';\\n\";\n\n    var argument = settings.variable;\n    if (argument) {\n      // Insure against third-party code injection. (CVE-2021-23358)\n      if (!bareIdentifier.test(argument)) throw new Error(\n        'variable is not a bare identifier: ' + argument\n      );\n    } else {\n      // If a variable is not specified, place data values in local scope.\n      source = 'with(obj||{}){\\n' + source + '}\\n';\n      argument = 'obj';\n    }\n\n    source = \"var __t,__p='',__j=Array.prototype.join,\" +\n      \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\n      source + 'return __p;\\n';\n\n    var render;\n    try {\n      render = new Function(argument, '_', source);\n    } catch (e) {\n      e.source = source;\n      throw e;\n    }\n\n    var template = function(data) {\n      return render.call(this, data, _$1);\n    };\n\n    // Provide the compiled source as a convenience for precompilation.\n    template.source = 'function(' + argument + '){\\n' + source + '}';\n\n    return template;\n  }\n\n  // Traverses the children of `obj` along `path`. If a child is a function, it\n  // is invoked with its parent as context. Returns the value of the final\n  // child, or `fallback` if any child is undefined.\n  function result(obj, path, fallback) {\n    path = toPath(path);\n    var length = path.length;\n    if (!length) {\n      return isFunction$1(fallback) ? fallback.call(obj) : fallback;\n    }\n    for (var i = 0; i < length; i++) {\n      var prop = obj == null ? void 0 : obj[path[i]];\n      if (prop === void 0) {\n        prop = fallback;\n        i = length; // Ensure we don't continue iterating.\n      }\n      obj = isFunction$1(prop) ? prop.call(obj) : prop;\n    }\n    return obj;\n  }\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  function uniqueId(prefix) {\n    var id = ++idCounter + '';\n    return prefix ? prefix + id : id;\n  }\n\n  // Start chaining a wrapped Underscore object.\n  function chain(obj) {\n    var instance = _$1(obj);\n    instance._chain = true;\n    return instance;\n  }\n\n  // Internal function to execute `sourceFunc` bound to `context` with optional\n  // `args`. Determines whether to execute a function as a constructor or as a\n  // normal function.\n  function executeBound(sourceFunc, boundFunc, context, callingContext, args) {\n    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);\n    var self = baseCreate(sourceFunc.prototype);\n    var result = sourceFunc.apply(self, args);\n    if (isObject(result)) return result;\n    return self;\n  }\n\n  // Partially apply a function by creating a version that has had some of its\n  // arguments pre-filled, without changing its dynamic `this` context. `_` acts\n  // as a placeholder by default, allowing any combination of arguments to be\n  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.\n  var partial = restArguments(function(func, boundArgs) {\n    var placeholder = partial.placeholder;\n    var bound = function() {\n      var position = 0, length = boundArgs.length;\n      var args = Array(length);\n      for (var i = 0; i < length; i++) {\n        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];\n      }\n      while (position < arguments.length) args.push(arguments[position++]);\n      return executeBound(func, bound, this, this, args);\n    };\n    return bound;\n  });\n\n  partial.placeholder = _$1;\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally).\n  var bind = restArguments(function(func, context, args) {\n    if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');\n    var bound = restArguments(function(callArgs) {\n      return executeBound(func, bound, context, this, args.concat(callArgs));\n    });\n    return bound;\n  });\n\n  // Internal helper for collection methods to determine whether a collection\n  // should be iterated as an array or as an object.\n  // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength\n  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094\n  var isArrayLike = createSizePropertyCheck(getLength);\n\n  // Internal implementation of a recursive `flatten` function.\n  function flatten$1(input, depth, strict, output) {\n    output = output || [];\n    if (!depth && depth !== 0) {\n      depth = Infinity;\n    } else if (depth <= 0) {\n      return output.concat(input);\n    }\n    var idx = output.length;\n    for (var i = 0, length = getLength(input); i < length; i++) {\n      var value = input[i];\n      if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {\n        // Flatten current level of array or arguments object.\n        if (depth > 1) {\n          flatten$1(value, depth - 1, strict, output);\n          idx = output.length;\n        } else {\n          var j = 0, len = value.length;\n          while (j < len) output[idx++] = value[j++];\n        }\n      } else if (!strict) {\n        output[idx++] = value;\n      }\n    }\n    return output;\n  }\n\n  // Bind a number of an object's methods to that object. Remaining arguments\n  // are the method names to be bound. Useful for ensuring that all callbacks\n  // defined on an object belong to it.\n  var bindAll = restArguments(function(obj, keys) {\n    keys = flatten$1(keys, false, false);\n    var index = keys.length;\n    if (index < 1) throw new Error('bindAll must be passed function names');\n    while (index--) {\n      var key = keys[index];\n      obj[key] = bind(obj[key], obj);\n    }\n    return obj;\n  });\n\n  // Memoize an expensive function by storing its results.\n  function memoize(func, hasher) {\n    var memoize = function(key) {\n      var cache = memoize.cache;\n      var address = '' + (hasher ? hasher.apply(this, arguments) : key);\n      if (!has$1(cache, address)) cache[address] = func.apply(this, arguments);\n      return cache[address];\n    };\n    memoize.cache = {};\n    return memoize;\n  }\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  var delay = restArguments(function(func, wait, args) {\n    return setTimeout(function() {\n      return func.apply(null, args);\n    }, wait);\n  });\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  var defer = partial(delay, _$1, 1);\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time. Normally, the throttled function will run\n  // as much as it can, without ever going more than once per `wait` duration;\n  // but if you'd like to disable the execution on the leading edge, pass\n  // `{leading: false}`. To disable execution on the trailing edge, ditto.\n  function throttle(func, wait, options) {\n    var timeout, context, args, result;\n    var previous = 0;\n    if (!options) options = {};\n\n    var later = function() {\n      previous = options.leading === false ? 0 : now();\n      timeout = null;\n      result = func.apply(context, args);\n      if (!timeout) context = args = null;\n    };\n\n    var throttled = function() {\n      var _now = now();\n      if (!previous && options.leading === false) previous = _now;\n      var remaining = wait - (_now - previous);\n      context = this;\n      args = arguments;\n      if (remaining <= 0 || remaining > wait) {\n        if (timeout) {\n          clearTimeout(timeout);\n          timeout = null;\n        }\n        previous = _now;\n        result = func.apply(context, args);\n        if (!timeout) context = args = null;\n      } else if (!timeout && options.trailing !== false) {\n        timeout = setTimeout(later, remaining);\n      }\n      return result;\n    };\n\n    throttled.cancel = function() {\n      clearTimeout(timeout);\n      previous = 0;\n      timeout = context = args = null;\n    };\n\n    return throttled;\n  }\n\n  // When a sequence of calls of the returned function ends, the argument\n  // function is triggered. The end of a sequence is defined by the `wait`\n  // parameter. If `immediate` is passed, the argument function will be\n  // triggered at the beginning of the sequence instead of at the end.\n  function debounce(func, wait, immediate) {\n    var timeout, previous, args, result, context;\n\n    var later = function() {\n      var passed = now() - previous;\n      if (wait > passed) {\n        timeout = setTimeout(later, wait - passed);\n      } else {\n        timeout = null;\n        if (!immediate) result = func.apply(context, args);\n        // This check is needed because `func` can recursively invoke `debounced`.\n        if (!timeout) args = context = null;\n      }\n    };\n\n    var debounced = restArguments(function(_args) {\n      context = this;\n      args = _args;\n      previous = now();\n      if (!timeout) {\n        timeout = setTimeout(later, wait);\n        if (immediate) result = func.apply(context, args);\n      }\n      return result;\n    });\n\n    debounced.cancel = function() {\n      clearTimeout(timeout);\n      timeout = args = context = null;\n    };\n\n    return debounced;\n  }\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  function wrap(func, wrapper) {\n    return partial(wrapper, func);\n  }\n\n  // Returns a negated version of the passed-in predicate.\n  function negate(predicate) {\n    return function() {\n      return !predicate.apply(this, arguments);\n    };\n  }\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  function compose() {\n    var args = arguments;\n    var start = args.length - 1;\n    return function() {\n      var i = start;\n      var result = args[start].apply(this, arguments);\n      while (i--) result = args[i].call(this, result);\n      return result;\n    };\n  }\n\n  // Returns a function that will only be executed on and after the Nth call.\n  function after(times, func) {\n    return function() {\n      if (--times < 1) {\n        return func.apply(this, arguments);\n      }\n    };\n  }\n\n  // Returns a function that will only be executed up to (but not including) the\n  // Nth call.\n  function before(times, func) {\n    var memo;\n    return function() {\n      if (--times > 0) {\n        memo = func.apply(this, arguments);\n      }\n      if (times <= 1) func = null;\n      return memo;\n    };\n  }\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  var once = partial(before, 2);\n\n  // Returns the first key on an object that passes a truth test.\n  function findKey(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = keys(obj), key;\n    for (var i = 0, length = _keys.length; i < length; i++) {\n      key = _keys[i];\n      if (predicate(obj[key], key, obj)) return key;\n    }\n  }\n\n  // Internal function to generate `_.findIndex` and `_.findLastIndex`.\n  function createPredicateIndexFinder(dir) {\n    return function(array, predicate, context) {\n      predicate = cb(predicate, context);\n      var length = getLength(array);\n      var index = dir > 0 ? 0 : length - 1;\n      for (; index >= 0 && index < length; index += dir) {\n        if (predicate(array[index], index, array)) return index;\n      }\n      return -1;\n    };\n  }\n\n  // Returns the first index on an array-like that passes a truth test.\n  var findIndex = createPredicateIndexFinder(1);\n\n  // Returns the last index on an array-like that passes a truth test.\n  var findLastIndex = createPredicateIndexFinder(-1);\n\n  // Use a comparator function to figure out the smallest index at which\n  // an object should be inserted so as to maintain order. Uses binary search.\n  function sortedIndex(array, obj, iteratee, context) {\n    iteratee = cb(iteratee, context, 1);\n    var value = iteratee(obj);\n    var low = 0, high = getLength(array);\n    while (low < high) {\n      var mid = Math.floor((low + high) / 2);\n      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;\n    }\n    return low;\n  }\n\n  // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.\n  function createIndexFinder(dir, predicateFind, sortedIndex) {\n    return function(array, item, idx) {\n      var i = 0, length = getLength(array);\n      if (typeof idx == 'number') {\n        if (dir > 0) {\n          i = idx >= 0 ? idx : Math.max(idx + length, i);\n        } else {\n          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;\n        }\n      } else if (sortedIndex && idx && length) {\n        idx = sortedIndex(array, item);\n        return array[idx] === item ? idx : -1;\n      }\n      if (item !== item) {\n        idx = predicateFind(slice.call(array, i, length), isNaN$1);\n        return idx >= 0 ? idx + i : -1;\n      }\n      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {\n        if (array[idx] === item) return idx;\n      }\n      return -1;\n    };\n  }\n\n  // Return the position of the first occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  var indexOf = createIndexFinder(1, findIndex, sortedIndex);\n\n  // Return the position of the last occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  var lastIndexOf = createIndexFinder(-1, findLastIndex);\n\n  // Return the first value which passes a truth test.\n  function find(obj, predicate, context) {\n    var keyFinder = isArrayLike(obj) ? findIndex : findKey;\n    var key = keyFinder(obj, predicate, context);\n    if (key !== void 0 && key !== -1) return obj[key];\n  }\n\n  // Convenience version of a common use case of `_.find`: getting the first\n  // object containing specific `key:value` pairs.\n  function findWhere(obj, attrs) {\n    return find(obj, matcher(attrs));\n  }\n\n  // The cornerstone for collection functions, an `each`\n  // implementation, aka `forEach`.\n  // Handles raw objects in addition to array-likes. Treats all\n  // sparse array-likes as if they were dense.\n  function each(obj, iteratee, context) {\n    iteratee = optimizeCb(iteratee, context);\n    var i, length;\n    if (isArrayLike(obj)) {\n      for (i = 0, length = obj.length; i < length; i++) {\n        iteratee(obj[i], i, obj);\n      }\n    } else {\n      var _keys = keys(obj);\n      for (i = 0, length = _keys.length; i < length; i++) {\n        iteratee(obj[_keys[i]], _keys[i], obj);\n      }\n    }\n    return obj;\n  }\n\n  // Return the results of applying the iteratee to each element.\n  function map(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length,\n        results = Array(length);\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      results[index] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  }\n\n  // Internal helper to create a reducing function, iterating left or right.\n  function createReduce(dir) {\n    // Wrap code that reassigns argument variables in a separate function than\n    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)\n    var reducer = function(obj, iteratee, memo, initial) {\n      var _keys = !isArrayLike(obj) && keys(obj),\n          length = (_keys || obj).length,\n          index = dir > 0 ? 0 : length - 1;\n      if (!initial) {\n        memo = obj[_keys ? _keys[index] : index];\n        index += dir;\n      }\n      for (; index >= 0 && index < length; index += dir) {\n        var currentKey = _keys ? _keys[index] : index;\n        memo = iteratee(memo, obj[currentKey], currentKey, obj);\n      }\n      return memo;\n    };\n\n    return function(obj, iteratee, memo, context) {\n      var initial = arguments.length >= 3;\n      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);\n    };\n  }\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`.\n  var reduce = createReduce(1);\n\n  // The right-associative version of reduce, also known as `foldr`.\n  var reduceRight = createReduce(-1);\n\n  // Return all the elements that pass a truth test.\n  function filter(obj, predicate, context) {\n    var results = [];\n    predicate = cb(predicate, context);\n    each(obj, function(value, index, list) {\n      if (predicate(value, index, list)) results.push(value);\n    });\n    return results;\n  }\n\n  // Return all the elements for which a truth test fails.\n  function reject(obj, predicate, context) {\n    return filter(obj, negate(cb(predicate)), context);\n  }\n\n  // Determine whether all of the elements pass a truth test.\n  function every(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      if (!predicate(obj[currentKey], currentKey, obj)) return false;\n    }\n    return true;\n  }\n\n  // Determine if at least one element in the object passes a truth test.\n  function some(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      if (predicate(obj[currentKey], currentKey, obj)) return true;\n    }\n    return false;\n  }\n\n  // Determine if the array or object contains a given item (using `===`).\n  function contains(obj, item, fromIndex, guard) {\n    if (!isArrayLike(obj)) obj = values(obj);\n    if (typeof fromIndex != 'number' || guard) fromIndex = 0;\n    return indexOf(obj, item, fromIndex) >= 0;\n  }\n\n  // Invoke a method (with arguments) on every item in a collection.\n  var invoke = restArguments(function(obj, path, args) {\n    var contextPath, func;\n    if (isFunction$1(path)) {\n      func = path;\n    } else {\n      path = toPath(path);\n      contextPath = path.slice(0, -1);\n      path = path[path.length - 1];\n    }\n    return map(obj, function(context) {\n      var method = func;\n      if (!method) {\n        if (contextPath && contextPath.length) {\n          context = deepGet(context, contextPath);\n        }\n        if (context == null) return void 0;\n        method = context[path];\n      }\n      return method == null ? method : method.apply(context, args);\n    });\n  });\n\n  // Convenience version of a common use case of `_.map`: fetching a property.\n  function pluck(obj, key) {\n    return map(obj, property(key));\n  }\n\n  // Convenience version of a common use case of `_.filter`: selecting only\n  // objects containing specific `key:value` pairs.\n  function where(obj, attrs) {\n    return filter(obj, matcher(attrs));\n  }\n\n  // Return the maximum element (or element-based computation).\n  function max(obj, iteratee, context) {\n    var result = -Infinity, lastComputed = -Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value > result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  }\n\n  // Return the minimum element (or element-based computation).\n  function min(obj, iteratee, context) {\n    var result = Infinity, lastComputed = Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value < result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed < lastComputed || computed === Infinity && result === Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  }\n\n  // Sample **n** random values from a collection using the modern version of the\n  // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).\n  // If **n** is not specified, returns a single random element.\n  // The internal `guard` argument allows it to work with `_.map`.\n  function sample(obj, n, guard) {\n    if (n == null || guard) {\n      if (!isArrayLike(obj)) obj = values(obj);\n      return obj[random(obj.length - 1)];\n    }\n    var sample = isArrayLike(obj) ? clone(obj) : values(obj);\n    var length = getLength(sample);\n    n = Math.max(Math.min(n, length), 0);\n    var last = length - 1;\n    for (var index = 0; index < n; index++) {\n      var rand = random(index, last);\n      var temp = sample[index];\n      sample[index] = sample[rand];\n      sample[rand] = temp;\n    }\n    return sample.slice(0, n);\n  }\n\n  // Shuffle a collection.\n  function shuffle(obj) {\n    return sample(obj, Infinity);\n  }\n\n  // Sort the object's values by a criterion produced by an iteratee.\n  function sortBy(obj, iteratee, context) {\n    var index = 0;\n    iteratee = cb(iteratee, context);\n    return pluck(map(obj, function(value, key, list) {\n      return {\n        value: value,\n        index: index++,\n        criteria: iteratee(value, key, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria;\n      var b = right.criteria;\n      if (a !== b) {\n        if (a > b || a === void 0) return 1;\n        if (a < b || b === void 0) return -1;\n      }\n      return left.index - right.index;\n    }), 'value');\n  }\n\n  // An internal function used for aggregate \"group by\" operations.\n  function group(behavior, partition) {\n    return function(obj, iteratee, context) {\n      var result = partition ? [[], []] : {};\n      iteratee = cb(iteratee, context);\n      each(obj, function(value, index) {\n        var key = iteratee(value, index, obj);\n        behavior(result, value, key);\n      });\n      return result;\n    };\n  }\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  var groupBy = group(function(result, value, key) {\n    if (has$1(result, key)) result[key].push(value); else result[key] = [value];\n  });\n\n  // Indexes the object's values by a criterion, similar to `_.groupBy`, but for\n  // when you know that your index values will be unique.\n  var indexBy = group(function(result, value, key) {\n    result[key] = value;\n  });\n\n  // Counts instances of an object that group by a certain criterion. Pass\n  // either a string attribute to count by, or a function that returns the\n  // criterion.\n  var countBy = group(function(result, value, key) {\n    if (has$1(result, key)) result[key]++; else result[key] = 1;\n  });\n\n  // Split a collection into two arrays: one whose elements all pass the given\n  // truth test, and one whose elements all do not pass the truth test.\n  var partition = group(function(result, value, pass) {\n    result[pass ? 0 : 1].push(value);\n  }, true);\n\n  // Safely create a real, live array from anything iterable.\n  var reStrSymbol = /[^\\ud800-\\udfff]|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff]/g;\n  function toArray(obj) {\n    if (!obj) return [];\n    if (isArray(obj)) return slice.call(obj);\n    if (isString(obj)) {\n      // Keep surrogate pair characters together.\n      return obj.match(reStrSymbol);\n    }\n    if (isArrayLike(obj)) return map(obj, identity);\n    return values(obj);\n  }\n\n  // Return the number of elements in a collection.\n  function size(obj) {\n    if (obj == null) return 0;\n    return isArrayLike(obj) ? obj.length : keys(obj).length;\n  }\n\n  // Internal `_.pick` helper function to determine whether `key` is an enumerable\n  // property name of `obj`.\n  function keyInObj(value, key, obj) {\n    return key in obj;\n  }\n\n  // Return a copy of the object only containing the allowed properties.\n  var pick = restArguments(function(obj, keys) {\n    var result = {}, iteratee = keys[0];\n    if (obj == null) return result;\n    if (isFunction$1(iteratee)) {\n      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);\n      keys = allKeys(obj);\n    } else {\n      iteratee = keyInObj;\n      keys = flatten$1(keys, false, false);\n      obj = Object(obj);\n    }\n    for (var i = 0, length = keys.length; i < length; i++) {\n      var key = keys[i];\n      var value = obj[key];\n      if (iteratee(value, key, obj)) result[key] = value;\n    }\n    return result;\n  });\n\n  // Return a copy of the object without the disallowed properties.\n  var omit = restArguments(function(obj, keys) {\n    var iteratee = keys[0], context;\n    if (isFunction$1(iteratee)) {\n      iteratee = negate(iteratee);\n      if (keys.length > 1) context = keys[1];\n    } else {\n      keys = map(flatten$1(keys, false, false), String);\n      iteratee = function(value, key) {\n        return !contains(keys, key);\n      };\n    }\n    return pick(obj, iteratee, context);\n  });\n\n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N.\n  function initial(array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n  }\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. The **guard** check allows it to work with `_.map`.\n  function first(array, n, guard) {\n    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];\n    if (n == null || guard) return array[0];\n    return initial(array, array.length - n);\n  }\n\n  // Returns everything but the first entry of the `array`. Especially useful on\n  // the `arguments` object. Passing an **n** will return the rest N values in the\n  // `array`.\n  function rest(array, n, guard) {\n    return slice.call(array, n == null || guard ? 1 : n);\n  }\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array.\n  function last(array, n, guard) {\n    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];\n    if (n == null || guard) return array[array.length - 1];\n    return rest(array, Math.max(0, array.length - n));\n  }\n\n  // Trim out all falsy values from an array.\n  function compact(array) {\n    return filter(array, Boolean);\n  }\n\n  // Flatten out an array, either recursively (by default), or up to `depth`.\n  // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.\n  function flatten(array, depth) {\n    return flatten$1(array, depth, false);\n  }\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  var difference = restArguments(function(array, rest) {\n    rest = flatten$1(rest, true, true);\n    return filter(array, function(value){\n      return !contains(rest, value);\n    });\n  });\n\n  // Return a version of the array that does not contain the specified value(s).\n  var without = restArguments(function(array, otherArrays) {\n    return difference(array, otherArrays);\n  });\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // The faster algorithm will not work with an iteratee if the iteratee\n  // is not a one-to-one function, so providing an iteratee will disable\n  // the faster algorithm.\n  function uniq(array, isSorted, iteratee, context) {\n    if (!isBoolean(isSorted)) {\n      context = iteratee;\n      iteratee = isSorted;\n      isSorted = false;\n    }\n    if (iteratee != null) iteratee = cb(iteratee, context);\n    var result = [];\n    var seen = [];\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var value = array[i],\n          computed = iteratee ? iteratee(value, i, array) : value;\n      if (isSorted && !iteratee) {\n        if (!i || seen !== computed) result.push(value);\n        seen = computed;\n      } else if (iteratee) {\n        if (!contains(seen, computed)) {\n          seen.push(computed);\n          result.push(value);\n        }\n      } else if (!contains(result, value)) {\n        result.push(value);\n      }\n    }\n    return result;\n  }\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  var union = restArguments(function(arrays) {\n    return uniq(flatten$1(arrays, true, true));\n  });\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays.\n  function intersection(array) {\n    var result = [];\n    var argsLength = arguments.length;\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var item = array[i];\n      if (contains(result, item)) continue;\n      var j;\n      for (j = 1; j < argsLength; j++) {\n        if (!contains(arguments[j], item)) break;\n      }\n      if (j === argsLength) result.push(item);\n    }\n    return result;\n  }\n\n  // Complement of zip. Unzip accepts an array of arrays and groups\n  // each array's elements on shared indices.\n  function unzip(array) {\n    var length = array && max(array, getLength).length || 0;\n    var result = Array(length);\n\n    for (var index = 0; index < length; index++) {\n      result[index] = pluck(array, index);\n    }\n    return result;\n  }\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  var zip = restArguments(unzip);\n\n  // Converts lists into objects. Pass either a single array of `[key, value]`\n  // pairs, or two parallel arrays of the same length -- one of keys, and one of\n  // the corresponding values. Passing by pairs is the reverse of `_.pairs`.\n  function object(list, values) {\n    var result = {};\n    for (var i = 0, length = getLength(list); i < length; i++) {\n      if (values) {\n        result[list[i]] = values[i];\n      } else {\n        result[list[i][0]] = list[i][1];\n      }\n    }\n    return result;\n  }\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](https://docs.python.org/library/functions.html#range).\n  function range(start, stop, step) {\n    if (stop == null) {\n      stop = start || 0;\n      start = 0;\n    }\n    if (!step) {\n      step = stop < start ? -1 : 1;\n    }\n\n    var length = Math.max(Math.ceil((stop - start) / step), 0);\n    var range = Array(length);\n\n    for (var idx = 0; idx < length; idx++, start += step) {\n      range[idx] = start;\n    }\n\n    return range;\n  }\n\n  // Chunk a single array into multiple arrays, each containing `count` or fewer\n  // items.\n  function chunk(array, count) {\n    if (count == null || count < 1) return [];\n    var result = [];\n    var i = 0, length = array.length;\n    while (i < length) {\n      result.push(slice.call(array, i, i += count));\n    }\n    return result;\n  }\n\n  // Helper function to continue chaining intermediate results.\n  function chainResult(instance, obj) {\n    return instance._chain ? _$1(obj).chain() : obj;\n  }\n\n  // Add your own custom functions to the Underscore object.\n  function mixin(obj) {\n    each(functions(obj), function(name) {\n      var func = _$1[name] = obj[name];\n      _$1.prototype[name] = function() {\n        var args = [this._wrapped];\n        push.apply(args, arguments);\n        return chainResult(this, func.apply(_$1, args));\n      };\n    });\n    return _$1;\n  }\n\n  // Add all mutator `Array` functions to the wrapper.\n  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    _$1.prototype[name] = function() {\n      var obj = this._wrapped;\n      if (obj != null) {\n        method.apply(obj, arguments);\n        if ((name === 'shift' || name === 'splice') && obj.length === 0) {\n          delete obj[0];\n        }\n      }\n      return chainResult(this, obj);\n    };\n  });\n\n  // Add all accessor `Array` functions to the wrapper.\n  each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    _$1.prototype[name] = function() {\n      var obj = this._wrapped;\n      if (obj != null) obj = method.apply(obj, arguments);\n      return chainResult(this, obj);\n    };\n  });\n\n  // Named Exports\n\n  var allExports = {\n    __proto__: null,\n    VERSION: VERSION,\n    restArguments: restArguments,\n    isObject: isObject,\n    isNull: isNull,\n    isUndefined: isUndefined,\n    isBoolean: isBoolean,\n    isElement: isElement,\n    isString: isString,\n    isNumber: isNumber,\n    isDate: isDate,\n    isRegExp: isRegExp,\n    isError: isError,\n    isSymbol: isSymbol,\n    isArrayBuffer: isArrayBuffer,\n    isDataView: isDataView$1,\n    isArray: isArray,\n    isFunction: isFunction$1,\n    isArguments: isArguments$1,\n    isFinite: isFinite$1,\n    isNaN: isNaN$1,\n    isTypedArray: isTypedArray$1,\n    isEmpty: isEmpty,\n    isMatch: isMatch,\n    isEqual: isEqual,\n    isMap: isMap,\n    isWeakMap: isWeakMap,\n    isSet: isSet,\n    isWeakSet: isWeakSet,\n    keys: keys,\n    allKeys: allKeys,\n    values: values,\n    pairs: pairs,\n    invert: invert,\n    functions: functions,\n    methods: functions,\n    extend: extend,\n    extendOwn: extendOwn,\n    assign: extendOwn,\n    defaults: defaults,\n    create: create,\n    clone: clone,\n    tap: tap,\n    get: get,\n    has: has,\n    mapObject: mapObject,\n    identity: identity,\n    constant: constant,\n    noop: noop,\n    toPath: toPath$1,\n    property: property,\n    propertyOf: propertyOf,\n    matcher: matcher,\n    matches: matcher,\n    times: times,\n    random: random,\n    now: now,\n    escape: _escape,\n    unescape: _unescape,\n    templateSettings: templateSettings,\n    template: template,\n    result: result,\n    uniqueId: uniqueId,\n    chain: chain,\n    iteratee: iteratee,\n    partial: partial,\n    bind: bind,\n    bindAll: bindAll,\n    memoize: memoize,\n    delay: delay,\n    defer: defer,\n    throttle: throttle,\n    debounce: debounce,\n    wrap: wrap,\n    negate: negate,\n    compose: compose,\n    after: after,\n    before: before,\n    once: once,\n    findKey: findKey,\n    findIndex: findIndex,\n    findLastIndex: findLastIndex,\n    sortedIndex: sortedIndex,\n    indexOf: indexOf,\n    lastIndexOf: lastIndexOf,\n    find: find,\n    detect: find,\n    findWhere: findWhere,\n    each: each,\n    forEach: each,\n    map: map,\n    collect: map,\n    reduce: reduce,\n    foldl: reduce,\n    inject: reduce,\n    reduceRight: reduceRight,\n    foldr: reduceRight,\n    filter: filter,\n    select: filter,\n    reject: reject,\n    every: every,\n    all: every,\n    some: some,\n    any: some,\n    contains: contains,\n    includes: contains,\n    include: contains,\n    invoke: invoke,\n    pluck: pluck,\n    where: where,\n    max: max,\n    min: min,\n    shuffle: shuffle,\n    sample: sample,\n    sortBy: sortBy,\n    groupBy: groupBy,\n    indexBy: indexBy,\n    countBy: countBy,\n    partition: partition,\n    toArray: toArray,\n    size: size,\n    pick: pick,\n    omit: omit,\n    first: first,\n    head: first,\n    take: first,\n    initial: initial,\n    last: last,\n    rest: rest,\n    tail: rest,\n    drop: rest,\n    compact: compact,\n    flatten: flatten,\n    without: without,\n    uniq: uniq,\n    unique: uniq,\n    union: union,\n    intersection: intersection,\n    difference: difference,\n    unzip: unzip,\n    transpose: unzip,\n    zip: zip,\n    object: object,\n    range: range,\n    chunk: chunk,\n    mixin: mixin,\n    'default': _$1\n  };\n\n  // Default Export\n\n  // Add all of the Underscore functions to the wrapper object.\n  var _ = mixin(allExports);\n  // Legacy Node.js API.\n  _._ = _;\n\n  return _;\n\n})));\n//# sourceMappingURL=underscore-umd.js.map\n"
  },
  {
    "path": "docs/_static/underscore-1.3.1.js",
    "content": "//     Underscore.js 1.3.1\n//     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.\n//     Underscore is freely distributable under the MIT license.\n//     Portions of Underscore are inspired or borrowed from Prototype,\n//     Oliver Steele's Functional, and John Resig's Micro-Templating.\n//     For all details and documentation:\n//     http://documentcloud.github.com/underscore\n\n(function() {\n\n  // Baseline setup\n  // --------------\n\n  // Establish the root object, `window` in the browser, or `global` on the server.\n  var root = this;\n\n  // Save the previous value of the `_` variable.\n  var previousUnderscore = root._;\n\n  // Establish the object that gets returned to break out of a loop iteration.\n  var breaker = {};\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var slice            = ArrayProto.slice,\n      unshift          = ArrayProto.unshift,\n      toString         = ObjProto.toString,\n      hasOwnProperty   = ObjProto.hasOwnProperty;\n\n  // All **ECMAScript 5** native function implementations that we hope to use\n  // are declared here.\n  var\n    nativeForEach      = ArrayProto.forEach,\n    nativeMap          = ArrayProto.map,\n    nativeReduce       = ArrayProto.reduce,\n    nativeReduceRight  = ArrayProto.reduceRight,\n    nativeFilter       = ArrayProto.filter,\n    nativeEvery        = ArrayProto.every,\n    nativeSome         = ArrayProto.some,\n    nativeIndexOf      = ArrayProto.indexOf,\n    nativeLastIndexOf  = ArrayProto.lastIndexOf,\n    nativeIsArray      = Array.isArray,\n    nativeKeys         = Object.keys,\n    nativeBind         = FuncProto.bind;\n\n  // Create a safe reference to the Underscore object for use below.\n  var _ = function(obj) { return new wrapper(obj); };\n\n  // Export the Underscore object for **Node.js**, with\n  // backwards-compatibility for the old `require()` API. If we're in\n  // the browser, add `_` as a global object via a string identifier,\n  // for Closure Compiler \"advanced\" mode.\n  if (typeof exports !== 'undefined') {\n    if (typeof module !== 'undefined' && module.exports) {\n      exports = module.exports = _;\n    }\n    exports._ = _;\n  } else {\n    root['_'] = _;\n  }\n\n  // Current version.\n  _.VERSION = '1.3.1';\n\n  // Collection Functions\n  // --------------------\n\n  // The cornerstone, an `each` implementation, aka `forEach`.\n  // Handles objects with the built-in `forEach`, arrays, and raw objects.\n  // Delegates to **ECMAScript 5**'s native `forEach` if available.\n  var each = _.each = _.forEach = function(obj, iterator, context) {\n    if (obj == null) return;\n    if (nativeForEach && obj.forEach === nativeForEach) {\n      obj.forEach(iterator, context);\n    } else if (obj.length === +obj.length) {\n      for (var i = 0, l = obj.length; i < l; i++) {\n        if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;\n      }\n    } else {\n      for (var key in obj) {\n        if (_.has(obj, key)) {\n          if (iterator.call(context, obj[key], key, obj) === breaker) return;\n        }\n      }\n    }\n  };\n\n  // Return the results of applying the iterator to each element.\n  // Delegates to **ECMAScript 5**'s native `map` if available.\n  _.map = _.collect = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);\n    each(obj, function(value, index, list) {\n      results[results.length] = iterator.call(context, value, index, list);\n    });\n    if (obj.length === +obj.length) results.length = obj.length;\n    return results;\n  };\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.\n  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {\n    var initial = arguments.length > 2;\n    if (obj == null) obj = [];\n    if (nativeReduce && obj.reduce === nativeReduce) {\n      if (context) iterator = _.bind(iterator, context);\n      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);\n    }\n    each(obj, function(value, index, list) {\n      if (!initial) {\n        memo = value;\n        initial = true;\n      } else {\n        memo = iterator.call(context, memo, value, index, list);\n      }\n    });\n    if (!initial) throw new TypeError('Reduce of empty array with no initial value');\n    return memo;\n  };\n\n  // The right-associative version of reduce, also known as `foldr`.\n  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.\n  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {\n    var initial = arguments.length > 2;\n    if (obj == null) obj = [];\n    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {\n      if (context) iterator = _.bind(iterator, context);\n      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);\n    }\n    var reversed = _.toArray(obj).reverse();\n    if (context && !initial) iterator = _.bind(iterator, context);\n    return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);\n  };\n\n  // Return the first value which passes a truth test. Aliased as `detect`.\n  _.find = _.detect = function(obj, iterator, context) {\n    var result;\n    any(obj, function(value, index, list) {\n      if (iterator.call(context, value, index, list)) {\n        result = value;\n        return true;\n      }\n    });\n    return result;\n  };\n\n  // Return all the elements that pass a truth test.\n  // Delegates to **ECMAScript 5**'s native `filter` if available.\n  // Aliased as `select`.\n  _.filter = _.select = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);\n    each(obj, function(value, index, list) {\n      if (iterator.call(context, value, index, list)) results[results.length] = value;\n    });\n    return results;\n  };\n\n  // Return all the elements for which a truth test fails.\n  _.reject = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    each(obj, function(value, index, list) {\n      if (!iterator.call(context, value, index, list)) results[results.length] = value;\n    });\n    return results;\n  };\n\n  // Determine whether all of the elements match a truth test.\n  // Delegates to **ECMAScript 5**'s native `every` if available.\n  // Aliased as `all`.\n  _.every = _.all = function(obj, iterator, context) {\n    var result = true;\n    if (obj == null) return result;\n    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);\n    each(obj, function(value, index, list) {\n      if (!(result = result && iterator.call(context, value, index, list))) return breaker;\n    });\n    return result;\n  };\n\n  // Determine if at least one element in the object matches a truth test.\n  // Delegates to **ECMAScript 5**'s native `some` if available.\n  // Aliased as `any`.\n  var any = _.some = _.any = function(obj, iterator, context) {\n    iterator || (iterator = _.identity);\n    var result = false;\n    if (obj == null) return result;\n    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);\n    each(obj, function(value, index, list) {\n      if (result || (result = iterator.call(context, value, index, list))) return breaker;\n    });\n    return !!result;\n  };\n\n  // Determine if a given value is included in the array or object using `===`.\n  // Aliased as `contains`.\n  _.include = _.contains = function(obj, target) {\n    var found = false;\n    if (obj == null) return found;\n    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;\n    found = any(obj, function(value) {\n      return value === target;\n    });\n    return found;\n  };\n\n  // Invoke a method (with arguments) on every item in a collection.\n  _.invoke = function(obj, method) {\n    var args = slice.call(arguments, 2);\n    return _.map(obj, function(value) {\n      return (_.isFunction(method) ? method || value : value[method]).apply(value, args);\n    });\n  };\n\n  // Convenience version of a common use case of `map`: fetching a property.\n  _.pluck = function(obj, key) {\n    return _.map(obj, function(value){ return value[key]; });\n  };\n\n  // Return the maximum element or (element-based computation).\n  _.max = function(obj, iterator, context) {\n    if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);\n    if (!iterator && _.isEmpty(obj)) return -Infinity;\n    var result = {computed : -Infinity};\n    each(obj, function(value, index, list) {\n      var computed = iterator ? iterator.call(context, value, index, list) : value;\n      computed >= result.computed && (result = {value : value, computed : computed});\n    });\n    return result.value;\n  };\n\n  // Return the minimum element (or element-based computation).\n  _.min = function(obj, iterator, context) {\n    if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);\n    if (!iterator && _.isEmpty(obj)) return Infinity;\n    var result = {computed : Infinity};\n    each(obj, function(value, index, list) {\n      var computed = iterator ? iterator.call(context, value, index, list) : value;\n      computed < result.computed && (result = {value : value, computed : computed});\n    });\n    return result.value;\n  };\n\n  // Shuffle an array.\n  _.shuffle = function(obj) {\n    var shuffled = [], rand;\n    each(obj, function(value, index, list) {\n      if (index == 0) {\n        shuffled[0] = value;\n      } else {\n        rand = Math.floor(Math.random() * (index + 1));\n        shuffled[index] = shuffled[rand];\n        shuffled[rand] = value;\n      }\n    });\n    return shuffled;\n  };\n\n  // Sort the object's values by a criterion produced by an iterator.\n  _.sortBy = function(obj, iterator, context) {\n    return _.pluck(_.map(obj, function(value, index, list) {\n      return {\n        value : value,\n        criteria : iterator.call(context, value, index, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria, b = right.criteria;\n      return a < b ? -1 : a > b ? 1 : 0;\n    }), 'value');\n  };\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  _.groupBy = function(obj, val) {\n    var result = {};\n    var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };\n    each(obj, function(value, index) {\n      var key = iterator(value, index);\n      (result[key] || (result[key] = [])).push(value);\n    });\n    return result;\n  };\n\n  // Use a comparator function to figure out at what index an object should\n  // be inserted so as to maintain order. Uses binary search.\n  _.sortedIndex = function(array, obj, iterator) {\n    iterator || (iterator = _.identity);\n    var low = 0, high = array.length;\n    while (low < high) {\n      var mid = (low + high) >> 1;\n      iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;\n    }\n    return low;\n  };\n\n  // Safely convert anything iterable into a real, live array.\n  _.toArray = function(iterable) {\n    if (!iterable)                return [];\n    if (iterable.toArray)         return iterable.toArray();\n    if (_.isArray(iterable))      return slice.call(iterable);\n    if (_.isArguments(iterable))  return slice.call(iterable);\n    return _.values(iterable);\n  };\n\n  // Return the number of elements in an object.\n  _.size = function(obj) {\n    return _.toArray(obj).length;\n  };\n\n  // Array Functions\n  // ---------------\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. Aliased as `head`. The **guard** check allows it to work\n  // with `_.map`.\n  _.first = _.head = function(array, n, guard) {\n    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];\n  };\n\n  // Returns everything but the last entry of the array. Especcialy useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N. The **guard** check allows it to work with\n  // `_.map`.\n  _.initial = function(array, n, guard) {\n    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));\n  };\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array. The **guard** check allows it to work with `_.map`.\n  _.last = function(array, n, guard) {\n    if ((n != null) && !guard) {\n      return slice.call(array, Math.max(array.length - n, 0));\n    } else {\n      return array[array.length - 1];\n    }\n  };\n\n  // Returns everything but the first entry of the array. Aliased as `tail`.\n  // Especially useful on the arguments object. Passing an **index** will return\n  // the rest of the values in the array from that index onward. The **guard**\n  // check allows it to work with `_.map`.\n  _.rest = _.tail = function(array, index, guard) {\n    return slice.call(array, (index == null) || guard ? 1 : index);\n  };\n\n  // Trim out all falsy values from an array.\n  _.compact = function(array) {\n    return _.filter(array, function(value){ return !!value; });\n  };\n\n  // Return a completely flattened version of an array.\n  _.flatten = function(array, shallow) {\n    return _.reduce(array, function(memo, value) {\n      if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));\n      memo[memo.length] = value;\n      return memo;\n    }, []);\n  };\n\n  // Return a version of the array that does not contain the specified value(s).\n  _.without = function(array) {\n    return _.difference(array, slice.call(arguments, 1));\n  };\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // Aliased as `unique`.\n  _.uniq = _.unique = function(array, isSorted, iterator) {\n    var initial = iterator ? _.map(array, iterator) : array;\n    var result = [];\n    _.reduce(initial, function(memo, el, i) {\n      if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {\n        memo[memo.length] = el;\n        result[result.length] = array[i];\n      }\n      return memo;\n    }, []);\n    return result;\n  };\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  _.union = function() {\n    return _.uniq(_.flatten(arguments, true));\n  };\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays. (Aliased as \"intersect\" for back-compat.)\n  _.intersection = _.intersect = function(array) {\n    var rest = slice.call(arguments, 1);\n    return _.filter(_.uniq(array), function(item) {\n      return _.every(rest, function(other) {\n        return _.indexOf(other, item) >= 0;\n      });\n    });\n  };\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  _.difference = function(array) {\n    var rest = _.flatten(slice.call(arguments, 1));\n    return _.filter(array, function(value){ return !_.include(rest, value); });\n  };\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  _.zip = function() {\n    var args = slice.call(arguments);\n    var length = _.max(_.pluck(args, 'length'));\n    var results = new Array(length);\n    for (var i = 0; i < length; i++) results[i] = _.pluck(args, \"\" + i);\n    return results;\n  };\n\n  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),\n  // we need this function. Return the position of the first occurrence of an\n  // item in an array, or -1 if the item is not included in the array.\n  // Delegates to **ECMAScript 5**'s native `indexOf` if available.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  _.indexOf = function(array, item, isSorted) {\n    if (array == null) return -1;\n    var i, l;\n    if (isSorted) {\n      i = _.sortedIndex(array, item);\n      return array[i] === item ? i : -1;\n    }\n    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);\n    for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;\n    return -1;\n  };\n\n  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.\n  _.lastIndexOf = function(array, item) {\n    if (array == null) return -1;\n    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);\n    var i = array.length;\n    while (i--) if (i in array && array[i] === item) return i;\n    return -1;\n  };\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](http://docs.python.org/library/functions.html#range).\n  _.range = function(start, stop, step) {\n    if (arguments.length <= 1) {\n      stop = start || 0;\n      start = 0;\n    }\n    step = arguments[2] || 1;\n\n    var len = Math.max(Math.ceil((stop - start) / step), 0);\n    var idx = 0;\n    var range = new Array(len);\n\n    while(idx < len) {\n      range[idx++] = start;\n      start += step;\n    }\n\n    return range;\n  };\n\n  // Function (ahem) Functions\n  // ------------------\n\n  // Reusable constructor function for prototype setting.\n  var ctor = function(){};\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally). Binding with arguments is also known as `curry`.\n  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.\n  // We check for `func.bind` first, to fail fast when `func` is undefined.\n  _.bind = function bind(func, context) {\n    var bound, args;\n    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));\n    if (!_.isFunction(func)) throw new TypeError;\n    args = slice.call(arguments, 2);\n    return bound = function() {\n      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));\n      ctor.prototype = func.prototype;\n      var self = new ctor;\n      var result = func.apply(self, args.concat(slice.call(arguments)));\n      if (Object(result) === result) return result;\n      return self;\n    };\n  };\n\n  // Bind all of an object's methods to that object. Useful for ensuring that\n  // all callbacks defined on an object belong to it.\n  _.bindAll = function(obj) {\n    var funcs = slice.call(arguments, 1);\n    if (funcs.length == 0) funcs = _.functions(obj);\n    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });\n    return obj;\n  };\n\n  // Memoize an expensive function by storing its results.\n  _.memoize = function(func, hasher) {\n    var memo = {};\n    hasher || (hasher = _.identity);\n    return function() {\n      var key = hasher.apply(this, arguments);\n      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));\n    };\n  };\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  _.delay = function(func, wait) {\n    var args = slice.call(arguments, 2);\n    return setTimeout(function(){ return func.apply(func, args); }, wait);\n  };\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  _.defer = function(func) {\n    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));\n  };\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time.\n  _.throttle = function(func, wait) {\n    var context, args, timeout, throttling, more;\n    var whenDone = _.debounce(function(){ more = throttling = false; }, wait);\n    return function() {\n      context = this; args = arguments;\n      var later = function() {\n        timeout = null;\n        if (more) func.apply(context, args);\n        whenDone();\n      };\n      if (!timeout) timeout = setTimeout(later, wait);\n      if (throttling) {\n        more = true;\n      } else {\n        func.apply(context, args);\n      }\n      whenDone();\n      throttling = true;\n    };\n  };\n\n  // Returns a function, that, as long as it continues to be invoked, will not\n  // be triggered. The function will be called after it stops being called for\n  // N milliseconds.\n  _.debounce = function(func, wait) {\n    var timeout;\n    return function() {\n      var context = this, args = arguments;\n      var later = function() {\n        timeout = null;\n        func.apply(context, args);\n      };\n      clearTimeout(timeout);\n      timeout = setTimeout(later, wait);\n    };\n  };\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  _.once = function(func) {\n    var ran = false, memo;\n    return function() {\n      if (ran) return memo;\n      ran = true;\n      return memo = func.apply(this, arguments);\n    };\n  };\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  _.wrap = function(func, wrapper) {\n    return function() {\n      var args = [func].concat(slice.call(arguments, 0));\n      return wrapper.apply(this, args);\n    };\n  };\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  _.compose = function() {\n    var funcs = arguments;\n    return function() {\n      var args = arguments;\n      for (var i = funcs.length - 1; i >= 0; i--) {\n        args = [funcs[i].apply(this, args)];\n      }\n      return args[0];\n    };\n  };\n\n  // Returns a function that will only be executed after being called N times.\n  _.after = function(times, func) {\n    if (times <= 0) return func();\n    return function() {\n      if (--times < 1) { return func.apply(this, arguments); }\n    };\n  };\n\n  // Object Functions\n  // ----------------\n\n  // Retrieve the names of an object's properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`\n  _.keys = nativeKeys || function(obj) {\n    if (obj !== Object(obj)) throw new TypeError('Invalid object');\n    var keys = [];\n    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;\n    return keys;\n  };\n\n  // Retrieve the values of an object's properties.\n  _.values = function(obj) {\n    return _.map(obj, _.identity);\n  };\n\n  // Return a sorted list of the function names available on the object.\n  // Aliased as `methods`\n  _.functions = _.methods = function(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (_.isFunction(obj[key])) names.push(key);\n    }\n    return names.sort();\n  };\n\n  // Extend a given object with all the properties in passed-in object(s).\n  _.extend = function(obj) {\n    each(slice.call(arguments, 1), function(source) {\n      for (var prop in source) {\n        obj[prop] = source[prop];\n      }\n    });\n    return obj;\n  };\n\n  // Fill in a given object with default properties.\n  _.defaults = function(obj) {\n    each(slice.call(arguments, 1), function(source) {\n      for (var prop in source) {\n        if (obj[prop] == null) obj[prop] = source[prop];\n      }\n    });\n    return obj;\n  };\n\n  // Create a (shallow-cloned) duplicate of an object.\n  _.clone = function(obj) {\n    if (!_.isObject(obj)) return obj;\n    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);\n  };\n\n  // Invokes interceptor with the obj, and then returns obj.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  _.tap = function(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  };\n\n  // Internal recursive comparison function.\n  function eq(a, b, stack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.\n    if (a === b) return a !== 0 || 1 / a == 1 / b;\n    // A strict comparison is necessary because `null == undefined`.\n    if (a == null || b == null) return a === b;\n    // Unwrap any wrapped objects.\n    if (a._chain) a = a._wrapped;\n    if (b._chain) b = b._wrapped;\n    // Invoke a custom `isEqual` method if one is provided.\n    if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);\n    if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className != toString.call(b)) return false;\n    switch (className) {\n      // Strings, numbers, dates, and booleans are compared by value.\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return a == String(b);\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for\n        // other numeric values.\n        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a == +b;\n      // RegExps are compared by their source patterns and flags.\n      case '[object RegExp]':\n        return a.source == b.source &&\n               a.global == b.global &&\n               a.multiline == b.multiline &&\n               a.ignoreCase == b.ignoreCase;\n    }\n    if (typeof a != 'object' || typeof b != 'object') return false;\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n    var length = stack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (stack[length] == a) return true;\n    }\n    // Add the first object to the stack of traversed objects.\n    stack.push(a);\n    var size = 0, result = true;\n    // Recursively compare objects and arrays.\n    if (className == '[object Array]') {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      size = a.length;\n      result = size == b.length;\n      if (result) {\n        // Deep compare the contents, ignoring non-numeric properties.\n        while (size--) {\n          // Ensure commutative equality for sparse arrays.\n          if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;\n        }\n      }\n    } else {\n      // Objects with different constructors are not equivalent.\n      if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;\n      // Deep compare objects.\n      for (var key in a) {\n        if (_.has(a, key)) {\n          // Count the expected number of properties.\n          size++;\n          // Deep compare each member.\n          if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;\n        }\n      }\n      // Ensure that both objects contain the same number of properties.\n      if (result) {\n        for (key in b) {\n          if (_.has(b, key) && !(size--)) break;\n        }\n        result = !size;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    stack.pop();\n    return result;\n  }\n\n  // Perform a deep comparison to check if two objects are equal.\n  _.isEqual = function(a, b) {\n    return eq(a, b, []);\n  };\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  _.isEmpty = function(obj) {\n    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;\n    for (var key in obj) if (_.has(obj, key)) return false;\n    return true;\n  };\n\n  // Is a given value a DOM element?\n  _.isElement = function(obj) {\n    return !!(obj && obj.nodeType == 1);\n  };\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native Array.isArray\n  _.isArray = nativeIsArray || function(obj) {\n    return toString.call(obj) == '[object Array]';\n  };\n\n  // Is a given variable an object?\n  _.isObject = function(obj) {\n    return obj === Object(obj);\n  };\n\n  // Is a given variable an arguments object?\n  _.isArguments = function(obj) {\n    return toString.call(obj) == '[object Arguments]';\n  };\n  if (!_.isArguments(arguments)) {\n    _.isArguments = function(obj) {\n      return !!(obj && _.has(obj, 'callee'));\n    };\n  }\n\n  // Is a given value a function?\n  _.isFunction = function(obj) {\n    return toString.call(obj) == '[object Function]';\n  };\n\n  // Is a given value a string?\n  _.isString = function(obj) {\n    return toString.call(obj) == '[object String]';\n  };\n\n  // Is a given value a number?\n  _.isNumber = function(obj) {\n    return toString.call(obj) == '[object Number]';\n  };\n\n  // Is the given value `NaN`?\n  _.isNaN = function(obj) {\n    // `NaN` is the only value for which `===` is not reflexive.\n    return obj !== obj;\n  };\n\n  // Is a given value a boolean?\n  _.isBoolean = function(obj) {\n    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';\n  };\n\n  // Is a given value a date?\n  _.isDate = function(obj) {\n    return toString.call(obj) == '[object Date]';\n  };\n\n  // Is the given value a regular expression?\n  _.isRegExp = function(obj) {\n    return toString.call(obj) == '[object RegExp]';\n  };\n\n  // Is a given value equal to null?\n  _.isNull = function(obj) {\n    return obj === null;\n  };\n\n  // Is a given variable undefined?\n  _.isUndefined = function(obj) {\n    return obj === void 0;\n  };\n\n  // Has own property?\n  _.has = function(obj, key) {\n    return hasOwnProperty.call(obj, key);\n  };\n\n  // Utility Functions\n  // -----------------\n\n  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\n  // previous owner. Returns a reference to the Underscore object.\n  _.noConflict = function() {\n    root._ = previousUnderscore;\n    return this;\n  };\n\n  // Keep the identity function around for default iterators.\n  _.identity = function(value) {\n    return value;\n  };\n\n  // Run a function **n** times.\n  _.times = function (n, iterator, context) {\n    for (var i = 0; i < n; i++) iterator.call(context, i);\n  };\n\n  // Escape a string for HTML interpolation.\n  _.escape = function(string) {\n    return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\\//g,'&#x2F;');\n  };\n\n  // Add your own custom functions to the Underscore object, ensuring that\n  // they're correctly added to the OOP wrapper as well.\n  _.mixin = function(obj) {\n    each(_.functions(obj), function(name){\n      addToWrapper(name, _[name] = obj[name]);\n    });\n  };\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  _.uniqueId = function(prefix) {\n    var id = idCounter++;\n    return prefix ? prefix + id : id;\n  };\n\n  // By default, Underscore uses ERB-style template delimiters, change the\n  // following template settings to use alternative delimiters.\n  _.templateSettings = {\n    evaluate    : /<%([\\s\\S]+?)%>/g,\n    interpolate : /<%=([\\s\\S]+?)%>/g,\n    escape      : /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /.^/;\n\n  // Within an interpolation, evaluation, or escaping, remove HTML escaping\n  // that had been previously added.\n  var unescape = function(code) {\n    return code.replace(/\\\\\\\\/g, '\\\\').replace(/\\\\'/g, \"'\");\n  };\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  _.template = function(str, data) {\n    var c  = _.templateSettings;\n    var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +\n      'with(obj||{}){__p.push(\\'' +\n      str.replace(/\\\\/g, '\\\\\\\\')\n         .replace(/'/g, \"\\\\'\")\n         .replace(c.escape || noMatch, function(match, code) {\n           return \"',_.escape(\" + unescape(code) + \"),'\";\n         })\n         .replace(c.interpolate || noMatch, function(match, code) {\n           return \"',\" + unescape(code) + \",'\";\n         })\n         .replace(c.evaluate || noMatch, function(match, code) {\n           return \"');\" + unescape(code).replace(/[\\r\\n\\t]/g, ' ') + \";__p.push('\";\n         })\n         .replace(/\\r/g, '\\\\r')\n         .replace(/\\n/g, '\\\\n')\n         .replace(/\\t/g, '\\\\t')\n         + \"');}return __p.join('');\";\n    var func = new Function('obj', '_', tmpl);\n    if (data) return func(data, _);\n    return function(data) {\n      return func.call(this, data, _);\n    };\n  };\n\n  // Add a \"chain\" function, which will delegate to the wrapper.\n  _.chain = function(obj) {\n    return _(obj).chain();\n  };\n\n  // The OOP Wrapper\n  // ---------------\n\n  // If Underscore is called as a function, it returns a wrapped object that\n  // can be used OO-style. This wrapper holds altered versions of all the\n  // underscore functions. Wrapped objects may be chained.\n  var wrapper = function(obj) { this._wrapped = obj; };\n\n  // Expose `wrapper.prototype` as `_.prototype`\n  _.prototype = wrapper.prototype;\n\n  // Helper function to continue chaining intermediate results.\n  var result = function(obj, chain) {\n    return chain ? _(obj).chain() : obj;\n  };\n\n  // A method to easily add functions to the OOP wrapper.\n  var addToWrapper = function(name, func) {\n    wrapper.prototype[name] = function() {\n      var args = slice.call(arguments);\n      unshift.call(args, this._wrapped);\n      return result(func.apply(_, args), this._chain);\n    };\n  };\n\n  // Add all of the Underscore functions to the wrapper object.\n  _.mixin(_);\n\n  // Add all mutator Array functions to the wrapper.\n  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    wrapper.prototype[name] = function() {\n      var wrapped = this._wrapped;\n      method.apply(wrapped, arguments);\n      var length = wrapped.length;\n      if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];\n      return result(wrapped, this._chain);\n    };\n  });\n\n  // Add all accessor Array functions to the wrapper.\n  each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    wrapper.prototype[name] = function() {\n      return result(method.apply(this._wrapped, arguments), this._chain);\n    };\n  });\n\n  // Start chaining a wrapped Underscore object.\n  wrapper.prototype.chain = function() {\n    this._chain = true;\n    return this;\n  };\n\n  // Extracts the result from a wrapped and chained object.\n  wrapper.prototype.value = function() {\n    return this._wrapped;\n  };\n\n}).call(this);\n"
  },
  {
    "path": "docs/_static/underscore.js",
    "content": "// Underscore.js 1.3.1\n// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.\n// Underscore is freely distributable under the MIT license.\n// Portions of Underscore are inspired or borrowed from Prototype,\n// Oliver Steele's Functional, and John Resig's Micro-Templating.\n// For all details and documentation:\n// http://documentcloud.github.com/underscore\n(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case \"[object String]\":return a==String(c);case \"[object Number]\":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case \"[object Date]\":case \"[object Boolean]\":return+a==+c;case \"[object RegExp]\":return a.source==\nc.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!=\"object\"||typeof c!=\"object\")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e==\"[object Array]\"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if(\"constructor\"in a!=\"constructor\"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,\nh)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!==\"undefined\"){if(typeof module!==\"undefined\"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION=\"1.3.1\";var j=b.each=\nb.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==\nnull&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError(\"Reduce of empty array with no initial value\");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=\nfunction(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=\ne&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=\nfunction(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});\nreturn e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),\"value\")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,\nc,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=\nb.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);\nreturn e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,\"length\")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,\"\"+e);return d};b.indexOf=function(a,c,\nd){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};\nvar F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,\nc){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:\na.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};\nb.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError(\"Invalid object\");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,\n1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)==\"[object Array]\"};b.isObject=function(a){return a===Object(a)};\nb.isArguments=function(a){return l.call(a)==\"[object Arguments]\"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,\"callee\"))};b.isFunction=function(a){return l.call(a)==\"[object Function]\"};b.isString=function(a){return l.call(a)==\"[object String]\"};b.isNumber=function(a){return l.call(a)==\"[object Number]\"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)==\"[object Boolean]\"};b.isDate=function(a){return l.call(a)==\"[object Date]\"};\nb.isRegExp=function(a){return l.call(a)==\"[object RegExp]\"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(\"\"+a).replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\").replace(/'/g,\"&#x27;\").replace(/\\//g,\"&#x2F;\")};b.mixin=function(a){j(b.functions(a),\nfunction(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\\s\\S]+?)%>/g,interpolate:/<%=([\\s\\S]+?)%>/g,escape:/<%-([\\s\\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\\\\\/g,\"\\\\\").replace(/\\\\'/g,\"'\")};b.template=function(a,c){var d=b.templateSettings,d=\"var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('\"+a.replace(/\\\\/g,\"\\\\\\\\\").replace(/'/g,\"\\\\'\").replace(d.escape||t,function(a,b){return\"',_.escape(\"+\nu(b)+\"),'\"}).replace(d.interpolate||t,function(a,b){return\"',\"+u(b)+\",'\"}).replace(d.evaluate||t,function(a,b){return\"');\"+u(b).replace(/[\\r\\n\\t]/g,\" \")+\";__p.push('\"}).replace(/\\r/g,\"\\\\r\").replace(/\\n/g,\"\\\\n\").replace(/\\t/g,\"\\\\t\")+\"');}return __p.join('');\",e=new Function(\"obj\",\"_\",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=\nfunction(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j(\"pop,push,reverse,shift,sort,splice,unshift\".split(\",\"),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a==\"shift\"||a==\"splice\")&&e===0&&delete d[0];return v(d,this._chain)}});j([\"concat\",\"join\",\"slice\"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=\ntrue;return this};m.prototype.value=function(){return this._wrapped}}).call(this);\n"
  },
  {
    "path": "docs/_static/websupport.js",
    "content": "/*\n * websupport.js\n * ~~~~~~~~~~~~~\n *\n * sphinx.websupport utilities for all documentation.\n *\n * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n(function($) {\n  $.fn.autogrow = function() {\n    return this.each(function() {\n    var textarea = this;\n\n    $.fn.autogrow.resize(textarea);\n\n    $(textarea)\n      .focus(function() {\n        textarea.interval = setInterval(function() {\n          $.fn.autogrow.resize(textarea);\n        }, 500);\n      })\n      .blur(function() {\n        clearInterval(textarea.interval);\n      });\n    });\n  };\n\n  $.fn.autogrow.resize = function(textarea) {\n    var lineHeight = parseInt($(textarea).css('line-height'), 10);\n    var lines = textarea.value.split('\\n');\n    var columns = textarea.cols;\n    var lineCount = 0;\n    $.each(lines, function() {\n      lineCount += Math.ceil(this.length / columns) || 1;\n    });\n    var height = lineHeight * (lineCount + 1);\n    $(textarea).css('height', height);\n  };\n})(jQuery);\n\n(function($) {\n  var comp, by;\n\n  function init() {\n    initEvents();\n    initComparator();\n  }\n\n  function initEvents() {\n    $(document).on(\"click\", 'a.comment-close', function(event) {\n      event.preventDefault();\n      hide($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.vote', function(event) {\n      event.preventDefault();\n      handleVote($(this));\n    });\n    $(document).on(\"click\", 'a.reply', function(event) {\n      event.preventDefault();\n      openReply($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.close-reply', function(event) {\n      event.preventDefault();\n      closeReply($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.sort-option', function(event) {\n      event.preventDefault();\n      handleReSort($(this));\n    });\n    $(document).on(\"click\", 'a.show-proposal', function(event) {\n      event.preventDefault();\n      showProposal($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.hide-proposal', function(event) {\n      event.preventDefault();\n      hideProposal($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.show-propose-change', function(event) {\n      event.preventDefault();\n      showProposeChange($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.hide-propose-change', function(event) {\n      event.preventDefault();\n      hideProposeChange($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.accept-comment', function(event) {\n      event.preventDefault();\n      acceptComment($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.delete-comment', function(event) {\n      event.preventDefault();\n      deleteComment($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.comment-markup', function(event) {\n      event.preventDefault();\n      toggleCommentMarkupBox($(this).attr('id').substring(2));\n    });\n  }\n\n  /**\n   * Set comp, which is a comparator function used for sorting and\n   * inserting comments into the list.\n   */\n  function setComparator() {\n    // If the first three letters are \"asc\", sort in ascending order\n    // and remove the prefix.\n    if (by.substring(0,3) == 'asc') {\n      var i = by.substring(3);\n      comp = function(a, b) { return a[i] - b[i]; };\n    } else {\n      // Otherwise sort in descending order.\n      comp = function(a, b) { return b[by] - a[by]; };\n    }\n\n    // Reset link styles and format the selected sort option.\n    $('a.sel').attr('href', '#').removeClass('sel');\n    $('a.by' + by).removeAttr('href').addClass('sel');\n  }\n\n  /**\n   * Create a comp function. If the user has preferences stored in\n   * the sortBy cookie, use those, otherwise use the default.\n   */\n  function initComparator() {\n    by = 'rating'; // Default to sort by rating.\n    // If the sortBy cookie is set, use that instead.\n    if (document.cookie.length > 0) {\n      var start = document.cookie.indexOf('sortBy=');\n      if (start != -1) {\n        start = start + 7;\n        var end = document.cookie.indexOf(\";\", start);\n        if (end == -1) {\n          end = document.cookie.length;\n          by = unescape(document.cookie.substring(start, end));\n        }\n      }\n    }\n    setComparator();\n  }\n\n  /**\n   * Show a comment div.\n   */\n  function show(id) {\n    $('#ao' + id).hide();\n    $('#ah' + id).show();\n    var context = $.extend({id: id}, opts);\n    var popup = $(renderTemplate(popupTemplate, context)).hide();\n    popup.find('textarea[name=\"proposal\"]').hide();\n    popup.find('a.by' + by).addClass('sel');\n    var form = popup.find('#cf' + id);\n    form.submit(function(event) {\n      event.preventDefault();\n      addComment(form);\n    });\n    $('#s' + id).after(popup);\n    popup.slideDown('fast', function() {\n      getComments(id);\n    });\n  }\n\n  /**\n   * Hide a comment div.\n   */\n  function hide(id) {\n    $('#ah' + id).hide();\n    $('#ao' + id).show();\n    var div = $('#sc' + id);\n    div.slideUp('fast', function() {\n      div.remove();\n    });\n  }\n\n  /**\n   * Perform an ajax request to get comments for a node\n   * and insert the comments into the comments tree.\n   */\n  function getComments(id) {\n    $.ajax({\n     type: 'GET',\n     url: opts.getCommentsURL,\n     data: {node: id},\n     success: function(data, textStatus, request) {\n       var ul = $('#cl' + id);\n       var speed = 100;\n       $('#cf' + id)\n         .find('textarea[name=\"proposal\"]')\n         .data('source', data.source);\n\n       if (data.comments.length === 0) {\n         ul.html('<li>No comments yet.</li>');\n         ul.data('empty', true);\n       } else {\n         // If there are comments, sort them and put them in the list.\n         var comments = sortComments(data.comments);\n         speed = data.comments.length * 100;\n         appendComments(comments, ul);\n         ul.data('empty', false);\n       }\n       $('#cn' + id).slideUp(speed + 200);\n       ul.slideDown(speed);\n     },\n     error: function(request, textStatus, error) {\n       showError('Oops, there was a problem retrieving the comments.');\n     },\n     dataType: 'json'\n    });\n  }\n\n  /**\n   * Add a comment via ajax and insert the comment into the comment tree.\n   */\n  function addComment(form) {\n    var node_id = form.find('input[name=\"node\"]').val();\n    var parent_id = form.find('input[name=\"parent\"]').val();\n    var text = form.find('textarea[name=\"comment\"]').val();\n    var proposal = form.find('textarea[name=\"proposal\"]').val();\n\n    if (text == '') {\n      showError('Please enter a comment.');\n      return;\n    }\n\n    // Disable the form that is being submitted.\n    form.find('textarea,input').attr('disabled', 'disabled');\n\n    // Send the comment to the server.\n    $.ajax({\n      type: \"POST\",\n      url: opts.addCommentURL,\n      dataType: 'json',\n      data: {\n        node: node_id,\n        parent: parent_id,\n        text: text,\n        proposal: proposal\n      },\n      success: function(data, textStatus, error) {\n        // Reset the form.\n        if (node_id) {\n          hideProposeChange(node_id);\n        }\n        form.find('textarea')\n          .val('')\n          .add(form.find('input'))\n          .removeAttr('disabled');\n\tvar ul = $('#cl' + (node_id || parent_id));\n        if (ul.data('empty')) {\n          $(ul).empty();\n          ul.data('empty', false);\n        }\n        insertComment(data.comment);\n        var ao = $('#ao' + node_id);\n        ao.find('img').attr({'src': opts.commentBrightImage});\n        if (node_id) {\n          // if this was a \"root\" comment, remove the commenting box\n          // (the user can get it back by reopening the comment popup)\n          $('#ca' + node_id).slideUp();\n        }\n      },\n      error: function(request, textStatus, error) {\n        form.find('textarea,input').removeAttr('disabled');\n        showError('Oops, there was a problem adding the comment.');\n      }\n    });\n  }\n\n  /**\n   * Recursively append comments to the main comment list and children\n   * lists, creating the comment tree.\n   */\n  function appendComments(comments, ul) {\n    $.each(comments, function() {\n      var div = createCommentDiv(this);\n      ul.append($(document.createElement('li')).html(div));\n      appendComments(this.children, div.find('ul.comment-children'));\n      // To avoid stagnating data, don't store the comments children in data.\n      this.children = null;\n      div.data('comment', this);\n    });\n  }\n\n  /**\n   * After adding a new comment, it must be inserted in the correct\n   * location in the comment tree.\n   */\n  function insertComment(comment) {\n    var div = createCommentDiv(comment);\n\n    // To avoid stagnating data, don't store the comments children in data.\n    comment.children = null;\n    div.data('comment', comment);\n\n    var ul = $('#cl' + (comment.node || comment.parent));\n    var siblings = getChildren(ul);\n\n    var li = $(document.createElement('li'));\n    li.hide();\n\n    // Determine where in the parents children list to insert this comment.\n    for(i=0; i < siblings.length; i++) {\n      if (comp(comment, siblings[i]) <= 0) {\n        $('#cd' + siblings[i].id)\n          .parent()\n          .before(li.html(div));\n        li.slideDown('fast');\n        return;\n      }\n    }\n\n    // If we get here, this comment rates lower than all the others,\n    // or it is the only comment in the list.\n    ul.append(li.html(div));\n    li.slideDown('fast');\n  }\n\n  function acceptComment(id) {\n    $.ajax({\n      type: 'POST',\n      url: opts.acceptCommentURL,\n      data: {id: id},\n      success: function(data, textStatus, request) {\n        $('#cm' + id).fadeOut('fast');\n        $('#cd' + id).removeClass('moderate');\n      },\n      error: function(request, textStatus, error) {\n        showError('Oops, there was a problem accepting the comment.');\n      }\n    });\n  }\n\n  function deleteComment(id) {\n    $.ajax({\n      type: 'POST',\n      url: opts.deleteCommentURL,\n      data: {id: id},\n      success: function(data, textStatus, request) {\n        var div = $('#cd' + id);\n        if (data == 'delete') {\n          // Moderator mode: remove the comment and all children immediately\n          div.slideUp('fast', function() {\n            div.remove();\n          });\n          return;\n        }\n        // User mode: only mark the comment as deleted\n        div\n          .find('span.user-id:first')\n          .text('[deleted]').end()\n          .find('div.comment-text:first')\n          .text('[deleted]').end()\n          .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +\n                ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)\n          .remove();\n        var comment = div.data('comment');\n        comment.username = '[deleted]';\n        comment.text = '[deleted]';\n        div.data('comment', comment);\n      },\n      error: function(request, textStatus, error) {\n        showError('Oops, there was a problem deleting the comment.');\n      }\n    });\n  }\n\n  function showProposal(id) {\n    $('#sp' + id).hide();\n    $('#hp' + id).show();\n    $('#pr' + id).slideDown('fast');\n  }\n\n  function hideProposal(id) {\n    $('#hp' + id).hide();\n    $('#sp' + id).show();\n    $('#pr' + id).slideUp('fast');\n  }\n\n  function showProposeChange(id) {\n    $('#pc' + id).hide();\n    $('#hc' + id).show();\n    var textarea = $('#pt' + id);\n    textarea.val(textarea.data('source'));\n    $.fn.autogrow.resize(textarea[0]);\n    textarea.slideDown('fast');\n  }\n\n  function hideProposeChange(id) {\n    $('#hc' + id).hide();\n    $('#pc' + id).show();\n    var textarea = $('#pt' + id);\n    textarea.val('').removeAttr('disabled');\n    textarea.slideUp('fast');\n  }\n\n  function toggleCommentMarkupBox(id) {\n    $('#mb' + id).toggle();\n  }\n\n  /** Handle when the user clicks on a sort by link. */\n  function handleReSort(link) {\n    var classes = link.attr('class').split(/\\s+/);\n    for (var i=0; i<classes.length; i++) {\n      if (classes[i] != 'sort-option') {\n\tby = classes[i].substring(2);\n      }\n    }\n    setComparator();\n    // Save/update the sortBy cookie.\n    var expiration = new Date();\n    expiration.setDate(expiration.getDate() + 365);\n    document.cookie= 'sortBy=' + escape(by) +\n                     ';expires=' + expiration.toUTCString();\n    $('ul.comment-ul').each(function(index, ul) {\n      var comments = getChildren($(ul), true);\n      comments = sortComments(comments);\n      appendComments(comments, $(ul).empty());\n    });\n  }\n\n  /**\n   * Function to process a vote when a user clicks an arrow.\n   */\n  function handleVote(link) {\n    if (!opts.voting) {\n      showError(\"You'll need to login to vote.\");\n      return;\n    }\n\n    var id = link.attr('id');\n    if (!id) {\n      // Didn't click on one of the voting arrows.\n      return;\n    }\n    // If it is an unvote, the new vote value is 0,\n    // Otherwise it's 1 for an upvote, or -1 for a downvote.\n    var value = 0;\n    if (id.charAt(1) != 'u') {\n      value = id.charAt(0) == 'u' ? 1 : -1;\n    }\n    // The data to be sent to the server.\n    var d = {\n      comment_id: id.substring(2),\n      value: value\n    };\n\n    // Swap the vote and unvote links.\n    link.hide();\n    $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)\n      .show();\n\n    // The div the comment is displayed in.\n    var div = $('div#cd' + d.comment_id);\n    var data = div.data('comment');\n\n    // If this is not an unvote, and the other vote arrow has\n    // already been pressed, unpress it.\n    if ((d.value !== 0) && (data.vote === d.value * -1)) {\n      $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();\n      $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();\n    }\n\n    // Update the comments rating in the local data.\n    data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);\n    data.vote = d.value;\n    div.data('comment', data);\n\n    // Change the rating text.\n    div.find('.rating:first')\n      .text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));\n\n    // Send the vote information to the server.\n    $.ajax({\n      type: \"POST\",\n      url: opts.processVoteURL,\n      data: d,\n      error: function(request, textStatus, error) {\n        showError('Oops, there was a problem casting that vote.');\n      }\n    });\n  }\n\n  /**\n   * Open a reply form used to reply to an existing comment.\n   */\n  function openReply(id) {\n    // Swap out the reply link for the hide link\n    $('#rl' + id).hide();\n    $('#cr' + id).show();\n\n    // Add the reply li to the children ul.\n    var div = $(renderTemplate(replyTemplate, {id: id})).hide();\n    $('#cl' + id)\n      .prepend(div)\n      // Setup the submit handler for the reply form.\n      .find('#rf' + id)\n      .submit(function(event) {\n        event.preventDefault();\n        addComment($('#rf' + id));\n        closeReply(id);\n      })\n      .find('input[type=button]')\n      .click(function() {\n        closeReply(id);\n      });\n    div.slideDown('fast', function() {\n      $('#rf' + id).find('textarea').focus();\n    });\n  }\n\n  /**\n   * Close the reply form opened with openReply.\n   */\n  function closeReply(id) {\n    // Remove the reply div from the DOM.\n    $('#rd' + id).slideUp('fast', function() {\n      $(this).remove();\n    });\n\n    // Swap out the hide link for the reply link\n    $('#cr' + id).hide();\n    $('#rl' + id).show();\n  }\n\n  /**\n   * Recursively sort a tree of comments using the comp comparator.\n   */\n  function sortComments(comments) {\n    comments.sort(comp);\n    $.each(comments, function() {\n      this.children = sortComments(this.children);\n    });\n    return comments;\n  }\n\n  /**\n   * Get the children comments from a ul. If recursive is true,\n   * recursively include childrens' children.\n   */\n  function getChildren(ul, recursive) {\n    var children = [];\n    ul.children().children(\"[id^='cd']\")\n      .each(function() {\n        var comment = $(this).data('comment');\n        if (recursive)\n          comment.children = getChildren($(this).find('#cl' + comment.id), true);\n        children.push(comment);\n      });\n    return children;\n  }\n\n  /** Create a div to display a comment in. */\n  function createCommentDiv(comment) {\n    if (!comment.displayed && !opts.moderator) {\n      return $('<div class=\"moderate\">Thank you!  Your comment will show up '\n               + 'once it is has been approved by a moderator.</div>');\n    }\n    // Prettify the comment rating.\n    comment.pretty_rating = comment.rating + ' point' +\n      (comment.rating == 1 ? '' : 's');\n    // Make a class (for displaying not yet moderated comments differently)\n    comment.css_class = comment.displayed ? '' : ' moderate';\n    // Create a div for this comment.\n    var context = $.extend({}, opts, comment);\n    var div = $(renderTemplate(commentTemplate, context));\n\n    // If the user has voted on this comment, highlight the correct arrow.\n    if (comment.vote) {\n      var direction = (comment.vote == 1) ? 'u' : 'd';\n      div.find('#' + direction + 'v' + comment.id).hide();\n      div.find('#' + direction + 'u' + comment.id).show();\n    }\n\n    if (opts.moderator || comment.text != '[deleted]') {\n      div.find('a.reply').show();\n      if (comment.proposal_diff)\n        div.find('#sp' + comment.id).show();\n      if (opts.moderator && !comment.displayed)\n        div.find('#cm' + comment.id).show();\n      if (opts.moderator || (opts.username == comment.username))\n        div.find('#dc' + comment.id).show();\n    }\n    return div;\n  }\n\n  /**\n   * A simple template renderer. Placeholders such as <%id%> are replaced\n   * by context['id'] with items being escaped. Placeholders such as <#id#>\n   * are not escaped.\n   */\n  function renderTemplate(template, context) {\n    var esc = $(document.createElement('div'));\n\n    function handle(ph, escape) {\n      var cur = context;\n      $.each(ph.split('.'), function() {\n        cur = cur[this];\n      });\n      return escape ? esc.text(cur || \"\").html() : cur;\n    }\n\n    return template.replace(/<([%#])([\\w\\.]*)\\1>/g, function() {\n      return handle(arguments[2], arguments[1] == '%' ? true : false);\n    });\n  }\n\n  /** Flash an error message briefly. */\n  function showError(message) {\n    $(document.createElement('div')).attr({'class': 'popup-error'})\n      .append($(document.createElement('div'))\n               .attr({'class': 'error-message'}).text(message))\n      .appendTo('body')\n      .fadeIn(\"slow\")\n      .delay(2000)\n      .fadeOut(\"slow\");\n  }\n\n  /** Add a link the user uses to open the comments popup. */\n  $.fn.comment = function() {\n    return this.each(function() {\n      var id = $(this).attr('id').substring(1);\n      var count = COMMENT_METADATA[id];\n      var title = count + ' comment' + (count == 1 ? '' : 's');\n      var image = count > 0 ? opts.commentBrightImage : opts.commentImage;\n      var addcls = count == 0 ? ' nocomment' : '';\n      $(this)\n        .append(\n          $(document.createElement('a')).attr({\n            href: '#',\n            'class': 'sphinx-comment-open' + addcls,\n            id: 'ao' + id\n          })\n            .append($(document.createElement('img')).attr({\n              src: image,\n              alt: 'comment',\n              title: title\n            }))\n            .click(function(event) {\n              event.preventDefault();\n              show($(this).attr('id').substring(2));\n            })\n        )\n        .append(\n          $(document.createElement('a')).attr({\n            href: '#',\n            'class': 'sphinx-comment-close hidden',\n            id: 'ah' + id\n          })\n            .append($(document.createElement('img')).attr({\n              src: opts.closeCommentImage,\n              alt: 'close',\n              title: 'close'\n            }))\n            .click(function(event) {\n              event.preventDefault();\n              hide($(this).attr('id').substring(2));\n            })\n        );\n    });\n  };\n\n  var opts = {\n    processVoteURL: '/_process_vote',\n    addCommentURL: '/_add_comment',\n    getCommentsURL: '/_get_comments',\n    acceptCommentURL: '/_accept_comment',\n    deleteCommentURL: '/_delete_comment',\n    commentImage: '/static/_static/comment.png',\n    closeCommentImage: '/static/_static/comment-close.png',\n    loadingImage: '/static/_static/ajax-loader.gif',\n    commentBrightImage: '/static/_static/comment-bright.png',\n    upArrow: '/static/_static/up.png',\n    downArrow: '/static/_static/down.png',\n    upArrowPressed: '/static/_static/up-pressed.png',\n    downArrowPressed: '/static/_static/down-pressed.png',\n    voting: false,\n    moderator: false\n  };\n\n  if (typeof COMMENT_OPTIONS != \"undefined\") {\n    opts = jQuery.extend(opts, COMMENT_OPTIONS);\n  }\n\n  var popupTemplate = '\\\n    <div class=\"sphinx-comments\" id=\"sc<%id%>\">\\\n      <p class=\"sort-options\">\\\n        Sort by:\\\n        <a href=\"#\" class=\"sort-option byrating\">best rated</a>\\\n        <a href=\"#\" class=\"sort-option byascage\">newest</a>\\\n        <a href=\"#\" class=\"sort-option byage\">oldest</a>\\\n      </p>\\\n      <div class=\"comment-header\">Comments</div>\\\n      <div class=\"comment-loading\" id=\"cn<%id%>\">\\\n        loading comments... <img src=\"<%loadingImage%>\" alt=\"\" /></div>\\\n      <ul id=\"cl<%id%>\" class=\"comment-ul\"></ul>\\\n      <div id=\"ca<%id%>\">\\\n      <p class=\"add-a-comment\">Add a comment\\\n        (<a href=\"#\" class=\"comment-markup\" id=\"ab<%id%>\">markup</a>):</p>\\\n      <div class=\"comment-markup-box\" id=\"mb<%id%>\">\\\n        reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \\\n        <code>``code``</code>, \\\n        code blocks: <code>::</code> and an indented block after blank line</div>\\\n      <form method=\"post\" id=\"cf<%id%>\" class=\"comment-form\" action=\"\">\\\n        <textarea name=\"comment\" cols=\"80\"></textarea>\\\n        <p class=\"propose-button\">\\\n          <a href=\"#\" id=\"pc<%id%>\" class=\"show-propose-change\">\\\n            Propose a change &#9657;\\\n          </a>\\\n          <a href=\"#\" id=\"hc<%id%>\" class=\"hide-propose-change\">\\\n            Propose a change &#9663;\\\n          </a>\\\n        </p>\\\n        <textarea name=\"proposal\" id=\"pt<%id%>\" cols=\"80\"\\\n                  spellcheck=\"false\"></textarea>\\\n        <input type=\"submit\" value=\"Add comment\" />\\\n        <input type=\"hidden\" name=\"node\" value=\"<%id%>\" />\\\n        <input type=\"hidden\" name=\"parent\" value=\"\" />\\\n      </form>\\\n      </div>\\\n    </div>';\n\n  var commentTemplate = '\\\n    <div id=\"cd<%id%>\" class=\"sphinx-comment<%css_class%>\">\\\n      <div class=\"vote\">\\\n        <div class=\"arrow\">\\\n          <a href=\"#\" id=\"uv<%id%>\" class=\"vote\" title=\"vote up\">\\\n            <img src=\"<%upArrow%>\" />\\\n          </a>\\\n          <a href=\"#\" id=\"uu<%id%>\" class=\"un vote\" title=\"vote up\">\\\n            <img src=\"<%upArrowPressed%>\" />\\\n          </a>\\\n        </div>\\\n        <div class=\"arrow\">\\\n          <a href=\"#\" id=\"dv<%id%>\" class=\"vote\" title=\"vote down\">\\\n            <img src=\"<%downArrow%>\" id=\"da<%id%>\" />\\\n          </a>\\\n          <a href=\"#\" id=\"du<%id%>\" class=\"un vote\" title=\"vote down\">\\\n            <img src=\"<%downArrowPressed%>\" />\\\n          </a>\\\n        </div>\\\n      </div>\\\n      <div class=\"comment-content\">\\\n        <p class=\"tagline comment\">\\\n          <span class=\"user-id\"><%username%></span>\\\n          <span class=\"rating\"><%pretty_rating%></span>\\\n          <span class=\"delta\"><%time.delta%></span>\\\n        </p>\\\n        <div class=\"comment-text comment\"><#text#></div>\\\n        <p class=\"comment-opts comment\">\\\n          <a href=\"#\" class=\"reply hidden\" id=\"rl<%id%>\">reply &#9657;</a>\\\n          <a href=\"#\" class=\"close-reply\" id=\"cr<%id%>\">reply &#9663;</a>\\\n          <a href=\"#\" id=\"sp<%id%>\" class=\"show-proposal\">proposal &#9657;</a>\\\n          <a href=\"#\" id=\"hp<%id%>\" class=\"hide-proposal\">proposal &#9663;</a>\\\n          <a href=\"#\" id=\"dc<%id%>\" class=\"delete-comment hidden\">delete</a>\\\n          <span id=\"cm<%id%>\" class=\"moderation hidden\">\\\n            <a href=\"#\" id=\"ac<%id%>\" class=\"accept-comment\">accept</a>\\\n          </span>\\\n        </p>\\\n        <pre class=\"proposal\" id=\"pr<%id%>\">\\\n<#proposal_diff#>\\\n        </pre>\\\n          <ul class=\"comment-children\" id=\"cl<%id%>\"></ul>\\\n        </div>\\\n        <div class=\"clearleft\"></div>\\\n      </div>\\\n    </div>';\n\n  var replyTemplate = '\\\n    <li>\\\n      <div class=\"reply-div\" id=\"rd<%id%>\">\\\n        <form id=\"rf<%id%>\">\\\n          <textarea name=\"comment\" cols=\"80\"></textarea>\\\n          <input type=\"submit\" value=\"Add reply\" />\\\n          <input type=\"button\" value=\"Cancel\" />\\\n          <input type=\"hidden\" name=\"parent\" value=\"<%id%>\" />\\\n          <input type=\"hidden\" name=\"node\" value=\"\" />\\\n        </form>\\\n      </div>\\\n    </li>';\n\n  $(document).ready(function() {\n    init();\n  });\n})(jQuery);\n\n$(document).ready(function() {\n  // add comment anchors for all paragraphs that are commentable\n  $('.sphinx-has-comment').comment();\n\n  // highlight search words in search results\n  $(\"div.context\").each(function() {\n    var params = $.getQueryParameters();\n    var terms = (params.q) ? params.q[0].split(/\\s+/) : [];\n    var result = $(this);\n    $.each(terms, function() {\n      result.highlightText(this.toLowerCase(), 'highlighted');\n    });\n  });\n\n  // directly open comment window if requested\n  var anchor = document.location.hash;\n  if (anchor.substring(0, 9) == '#comment-') {\n    $('#ao' + anchor.substring(9)).click();\n    document.location.hash = '#s' + anchor.substring(9);\n  }\n});\n"
  },
  {
    "path": "docs/genindex.html",
    "content": "\n\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Index &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"#\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>Index</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n\n<h1 id=\"index\">Index</h1>\n\n<div class=\"genindex-jumpbox\">\n <a href=\"#_\"><strong>_</strong></a>\n | <a href=\"#A\"><strong>A</strong></a>\n | <a href=\"#B\"><strong>B</strong></a>\n | <a href=\"#C\"><strong>C</strong></a>\n | <a href=\"#D\"><strong>D</strong></a>\n | <a href=\"#E\"><strong>E</strong></a>\n | <a href=\"#F\"><strong>F</strong></a>\n | <a href=\"#G\"><strong>G</strong></a>\n | <a href=\"#H\"><strong>H</strong></a>\n | <a href=\"#I\"><strong>I</strong></a>\n | <a href=\"#L\"><strong>L</strong></a>\n | <a href=\"#M\"><strong>M</strong></a>\n | <a href=\"#N\"><strong>N</strong></a>\n | <a href=\"#O\"><strong>O</strong></a>\n | <a href=\"#P\"><strong>P</strong></a>\n | <a href=\"#R\"><strong>R</strong></a>\n | <a href=\"#S\"><strong>S</strong></a>\n | <a href=\"#T\"><strong>T</strong></a>\n | <a href=\"#U\"><strong>U</strong></a>\n | <a href=\"#V\"><strong>V</strong></a>\n | <a href=\"#W\"><strong>W</strong></a>\n | <a href=\"#X\"><strong>X</strong></a>\n | <a href=\"#Z\"><strong>Z</strong></a>\n \n</div>\n<h2 id=\"_\">_</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.__best\">__best (UCTB.train.EarlyStopping.EarlyStopping attribute)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.__best\">(UCTB.train.EarlyStopping.EarlyStoppingTTest attribute)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.__p\">__p (UCTB.train.EarlyStopping.EarlyStopping attribute)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.__p_value_threshold\">__p_value_threshold (UCTB.train.EarlyStopping.EarlyStoppingTTest attribute)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.__patience\">__patience (UCTB.train.EarlyStopping.EarlyStopping attribute)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.__record_list\">__record_list (UCTB.train.EarlyStopping.EarlyStopping attribute)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.__record_list\">(UCTB.train.EarlyStopping.EarlyStoppingTTest attribute)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.__test_length\">__test_length (UCTB.train.EarlyStopping.EarlyStoppingTTest attribute)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"A\">A</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL.add_ga_layer_matrix\">add_ga_layer_matrix() (UCTB.model_unit.GraphModelLayers.GAL static method)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GCL.add_gc_layer\">add_gc_layer() (UCTB.model_unit.GraphModelLayers.GCL static method)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GCL.add_multi_gc_layers\">add_multi_gc_layers() (UCTB.model_unit.GraphModelLayers.GCL static method)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL.add_residual_ga_layer\">add_residual_ga_layer() (UCTB.model_unit.GraphModelLayers.GAL static method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ARIMA.ARIMA.adf_test\">adf_test() (UCTB.model.ARIMA.ARIMA static method)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.adjacent_to_laplacian\">adjacent_to_laplacian() (UCTB.preprocess.GraphGenerator.GraphGenerator static method)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.AGCRN.AGCRN\">AGCRN (class in UCTB.model.AGCRN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.alias_draw\">alias_draw() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.alias_setup\">alias_setup() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.AM\">AM (UCTB.preprocess.GraphGenerator.GraphGenerator attribute)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ARIMA.ARIMA\">ARIMA (class in UCTB.model.ARIMA)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.ASTGCN_submodule\">ASTGCN_submodule (class in UCTB.model.ASTGCN)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL.attention_merge_weight\">attention_merge_weight() (UCTB.model_unit.GraphModelLayers.GAL static method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"B\">B</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\">BaseModel (class in UCTB.model_unit.BaseModel)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.DCRNN.DCRNN.build\">build() (UCTB.model.DCRNN.DCRNN method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.model.html#UCTB.model.DeepST.DeepST.build\">(UCTB.model.DeepST.DeepST method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.GeoMAN.GeoMAN.build\">(UCTB.model.GeoMAN.GeoMAN method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.STMeta.STMeta.build\">(UCTB.model.STMeta.STMeta method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.ST_MGCN.ST_MGCN.build\">(UCTB.model.ST_MGCN.ST_MGCN method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.ST_ResNet.ST_ResNet.build\">(UCTB.model.ST_ResNet.ST_ResNet method)</a>\n</li>\n        <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.build\">(UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.build_model\">build_model() (in module UCTB.model.STGCN)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"C\">C</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell.call\">call() (UCTB.model_unit.DCRNN_CELL.DCGRUCell method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.cheb_conv\">cheb_conv (class in UCTB.model.ASTGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.cheb_conv_withSAt\">cheb_conv_withSAt (class in UCTB.model.ASTGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.cheb_poly_approx\">cheb_poly_approx() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.cheb_polynomial\">cheb_polynomial() (in module UCTB.model.ASTGCN)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.chooseNormalizer\">chooseNormalizer() (in module UCTB.preprocess.preprocessor)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.close\">close() (UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell.compute_output_shape\">compute_output_shape() (UCTB.model_unit.DCRNN_CELL.DCGRUCell method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.construct_adj\">construct_adj() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.correlation_adjacent\">correlation_adjacent() (UCTB.preprocess.GraphGenerator.GraphGenerator static method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"D\">D</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.daily_slots\">daily_slots (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.data\">data (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet\">DataSet (class in UCTB.dataset.dataset)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.dataset\">dataset (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell\">DCGRUCell (class in UCTB.model_unit.DCRNN_CELL)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.DCRNN.DCRNN\">DCRNN (class in UCTB.model.DCRNN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.DeepST.DeepST\">DeepST (class in UCTB.model.DeepST)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.distance_adjacent\">distance_adjacent() (UCTB.preprocess.GraphGenerator.GraphGenerator method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"E\">E</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping\">EarlyStopping (class in UCTB.train.EarlyStopping)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest\">EarlyStoppingTTest (class in UCTB.train.EarlyStopping)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.external_dim\">external_dim (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"F\">F</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.XGBoost.XGBoost.fit\">fit() (UCTB.model.XGBoost.XGBoost method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.fit\">(UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.ASTGCN_submodule.forward\">forward() (UCTB.model.ASTGCN.ASTGCN_submodule method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.Spatial_Attention_layer.forward\">(UCTB.model.ASTGCN.Spatial_Attention_layer method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.cheb_conv.forward\">(UCTB.model.ASTGCN.cheb_conv method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.cheb_conv_withSAt.forward\">(UCTB.model.ASTGCN.cheb_conv_withSAt method)</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.fully_con_layer\">fully_con_layer() (in module UCTB.model.STGCN)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"G\">G</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL\">GAL (class in UCTB.model_unit.GraphModelLayers)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.gatedFusion\">gatedFusion() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GCL\">GCL (class in UCTB.model_unit.GraphModelLayers)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.ST_RNN.GCLSTMCell\">GCLSTMCell (class in UCTB.model_unit.ST_RNN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.gcn_operation\">gcn_operation() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.gconv\">gconv() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.gen_batch\">gen_batch() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GeoMAN.GeoMAN\">GeoMAN (class in UCTB.model.GeoMAN)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.get_adjacency_matrix\">get_adjacency_matrix() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.get_batch\">get_batch() (UCTB.train.MiniBatchTrain.MiniBatchFeedDict method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain.get_batch\">(UCTB.train.MiniBatchTrain.MiniBatchTrain method)</a>\n</li>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.get_batch\">(UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData method)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ARIMA.ARIMA.get_order\">get_order() (UCTB.model.ARIMA.ARIMA method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.GMAN\">GMAN() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator\">GraphGenerator (class in UCTB.preprocess.GraphGenerator)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GraphWaveNet.gwnet\">gwnet (class in UCTB.model.GraphWaveNet)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"H\">H</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.haversine\">haversine() (UCTB.preprocess.GraphGenerator.GraphGenerator static method)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.HM.HM\">HM (class in UCTB.model.HM)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"I\">I</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.GeoMAN.input_transform\">input_transform() (in module UCTB.model.GeoMAN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.interaction_adjacent\">interaction_adjacent() (UCTB.preprocess.GraphGenerator.GraphGenerator static method)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.MaxMinNormalizer.inverse_transform\">inverse_transform() (UCTB.preprocess.preprocessor.MaxMinNormalizer method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.WhiteNormalizer.inverse_transform\">(UCTB.preprocess.preprocessor.WhiteNormalizer method)</a>\n</li>\n        <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.ZscoreNormalizer.inverse_transform\">(UCTB.preprocess.preprocessor.ZscoreNormalizer method)</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.time_utils.is_valid_date\">is_valid_date() (in module UCTB.preprocess.time_utils)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.time_utils.is_work_day_america\">is_work_day_america() (in module UCTB.preprocess.time_utils)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.time_utils.is_work_day_china\">is_work_day_china() (in module UCTB.preprocess.time_utils)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"L\">L</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.layer_norm\">layer_norm() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.LM\">LM (UCTB.preprocess.GraphGenerator.GraphGenerator attribute)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.load\">load() (UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.load_event_scalar\">load_event_scalar() (UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"M\">M</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.mae\">mae() (in module UCTB.evaluation.metric)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.make_concat\">make_concat() (UCTB.dataset.data_loader.NodeTrafficLoader method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.make_model\">make_model() (in module UCTB.model.ASTGCN)</a>\n</li>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.mape\">mape() (in module UCTB.evaluation.metric)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.MaxMinNormalizer\">MaxMinNormalizer (class in UCTB.preprocess.preprocessor)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.merge_data\">merge_data() (UCTB.dataset.dataset.DataSet method)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.MergeIndex\">MergeIndex (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.MergeWay\">MergeWay (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict\">MiniBatchFeedDict (class in UCTB.train.MiniBatchTrain)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain\">MiniBatchTrain (class in UCTB.train.MiniBatchTrain)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData\">MiniBatchTrainMultiData (class in UCTB.train.MiniBatchTrain)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.ST_MoveSample.move_sample\">move_sample() (UCTB.preprocess.preprocessor.ST_MoveSample method)</a>\n</li>\n      <li><a href=\"UCTB.utils.html#UCTB.utils.multi_threads.multiple_process\">multiple_process() (in module UCTB.utils.multi_threads)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"N\">N</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.node_monthly_interaction\">node_monthly_interaction (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.node_station_info\">node_station_info (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.node_traffic\">node_traffic (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader\">NodeTrafficLoader (class in UCTB.dataset.data_loader)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.Normalizer\">Normalizer (class in UCTB.preprocess.preprocessor)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"O\">O</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.output_layer\">output_layer() (in module UCTB.model.STGCN)</a>\n\n      <ul>\n        <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.output_layer\">(in module UCTB.model.STSGCN)</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell.output_size\">output_size (UCTB.model_unit.DCRNN_CELL.DCGRUCell attribute)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"P\">P</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.position_embedding\">position_embedding() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ARIMA.ARIMA.predict\">predict() (UCTB.model.ARIMA.ARIMA method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.model.html#UCTB.model.HM.HM.predict\">(UCTB.model.HM.HM method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.XGBoost.XGBoost.predict\">(UCTB.model.XGBoost.XGBoost method)</a>\n</li>\n        <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.predict\">(UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      </ul></li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"R\">R</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.restart\">restart() (UCTB.train.MiniBatchTrain.MiniBatchFeedDict method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain.restart\">(UCTB.train.MiniBatchTrain.MiniBatchTrain method)</a>\n</li>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.restart\">(UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData method)</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.rmse\">rmse() (in module UCTB.evaluation.metric)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"S\">S</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.save\">save() (UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.scaled_Laplacian_ASTGCN\">scaled_Laplacian_ASTGCN() (in module UCTB.preprocess.GraphGenerator)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.scaled_laplacian_STGCN\">scaled_laplacian_STGCN() (in module UCTB.preprocess.GraphGenerator)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.shuffle\">shuffle() (UCTB.train.MiniBatchTrain.MiniBatchFeedDict static method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain.shuffle\">(UCTB.train.MiniBatchTrain.MiniBatchTrain static method)</a>\n</li>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.shuffle\">(UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData static method)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.smape\">smape() (in module UCTB.evaluation.metric)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.Spatial_Attention_layer\">Spatial_Attention_layer (class in UCTB.model.ASTGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.spatialAttention\">spatialAttention() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.spatio_conv_layer\">spatio_conv_layer() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.SplitData.split_data\">split_data() (UCTB.preprocess.preprocessor.SplitData static method)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.SplitData.split_feed_dict\">split_feed_dict() (UCTB.preprocess.preprocessor.SplitData static method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GeoMAN.split_timesteps\">split_timesteps() (in module UCTB.model.GeoMAN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.SplitData\">SplitData (class in UCTB.preprocess.preprocessor)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.st_conv_block\">st_conv_block() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ST_MGCN.ST_MGCN\">ST_MGCN (class in UCTB.model.ST_MGCN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.ST_MoveSample\">ST_MoveSample (class in UCTB.preprocess.preprocessor)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ST_ResNet.ST_ResNet\">ST_ResNet (class in UCTB.model.ST_ResNet)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell.state_size\">state_size (UCTB.model_unit.DCRNN_CELL.DCGRUCell attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.station_number\">station_number (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.STEmbedding\">STEmbedding() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.sthgcn_layer_individual\">sthgcn_layer_individual() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.sthgcn_layer_sharing\">sthgcn_layer_sharing() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STMeta.STMeta\">STMeta (class in UCTB.model.STMeta)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.stop\">stop() (UCTB.train.EarlyStopping.EarlyStopping method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.stop\">(UCTB.train.EarlyStopping.EarlyStoppingTTest method)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.stsgcl\">stsgcl() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.stsgcm\">stsgcm() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.stsgcn\">stsgcn() (in module UCTB.model.STSGCN)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"T\">T</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.temporal_conv_layer\">temporal_conv_layer() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.temporalAttention\">temporalAttention() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.time_fitness\">time_fitness (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.time_range\">time_range (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.train_closeness\">train_closeness (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.train_y\">train_y (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.MaxMinNormalizer.transform\">transform() (UCTB.preprocess.preprocessor.MaxMinNormalizer method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.WhiteNormalizer.transform\">(UCTB.preprocess.preprocessor.WhiteNormalizer method)</a>\n</li>\n        <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.ZscoreNormalizer.transform\">(UCTB.preprocess.preprocessor.ZscoreNormalizer method)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.transformAttention\">transformAttention() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.trunc_mae\">trunc_mae() (in module UCTB.evaluation.metric)</a>\n</li>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.trunc_rmse\">trunc_rmse() (in module UCTB.evaluation.metric)</a>\n</li>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.trunc_smape\">trunc_smape() (in module UCTB.evaluation.metric)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"U\">U</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.html#module-UCTB\">UCTB (module)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#module-UCTB.dataset.data_loader\">UCTB.dataset.data_loader (module)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#module-UCTB.dataset.dataset\">UCTB.dataset.dataset (module)</a>\n</li>\n      <li><a href=\"UCTB.evaluation.html#module-UCTB.evaluation.metric\">UCTB.evaluation.metric (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.AGCRN\">UCTB.model.AGCRN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.ARIMA\">UCTB.model.ARIMA (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.ASTGCN\">UCTB.model.ASTGCN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.DCRNN\">UCTB.model.DCRNN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.DeepST\">UCTB.model.DeepST (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.GeoMAN\">UCTB.model.GeoMAN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.GMAN\">UCTB.model.GMAN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.GraphWaveNet\">UCTB.model.GraphWaveNet (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.HM\">UCTB.model.HM (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.ST_MGCN\">UCTB.model.ST_MGCN (module)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.ST_ResNet\">UCTB.model.ST_ResNet (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.STGCN\">UCTB.model.STGCN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.STMeta\">UCTB.model.STMeta (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.STSGCN\">UCTB.model.STSGCN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.XGBoost\">UCTB.model.XGBoost (module)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#module-UCTB.model_unit.BaseModel\">UCTB.model_unit.BaseModel (module)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#module-UCTB.model_unit.DCRNN_CELL\">UCTB.model_unit.DCRNN_CELL (module)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#module-UCTB.model_unit.GraphModelLayers\">UCTB.model_unit.GraphModelLayers (module)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#module-UCTB.model_unit.ST_RNN\">UCTB.model_unit.ST_RNN (module)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#module-UCTB.preprocess.GraphGenerator\">UCTB.preprocess.GraphGenerator (module)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#module-UCTB.preprocess.preprocessor\">UCTB.preprocess.preprocessor (module)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#module-UCTB.preprocess.time_utils\">UCTB.preprocess.time_utils (module)</a>\n</li>\n      <li><a href=\"UCTB.train.html#module-UCTB.train.EarlyStopping\">UCTB.train.EarlyStopping (module)</a>\n</li>\n      <li><a href=\"UCTB.train.html#module-UCTB.train.MiniBatchTrain\">UCTB.train.MiniBatchTrain (module)</a>\n</li>\n      <li><a href=\"UCTB.utils.html#module-UCTB.utils.multi_threads\">UCTB.utils.multi_threads (module)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"V\">V</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.variable_summaries\">variable_summaries() (in module UCTB.model.STGCN)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"W\">W</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.WhiteNormalizer\">WhiteNormalizer (class in UCTB.preprocess.preprocessor)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"X\">X</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.XGBoost.XGBoost\">XGBoost (class in UCTB.model.XGBoost)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"Z\">Z</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.ZscoreNormalizer\">ZscoreNormalizer (class in UCTB.preprocess.preprocessor)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/index.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Welcome to UCTB’s documentation! &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"#\"/>\n        <link rel=\"next\" title=\"1. Introduction\" href=\"md_file/introduction.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"#\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"#\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"#\">Docs</a> &raquo;</li>\n        \n      <li>Welcome to UCTB’s documentation!</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/index.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"welcome-to-uctb-s-documentation\">\n<h1>Welcome to UCTB’s documentation!<a class=\"headerlink\" href=\"#welcome-to-uctb-s-documentation\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/introduction.html#urban-datasts\">1.1. Urban Datasts</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/introduction.html#predictive-tool\">1.2. Predictive Tool</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/introduction.html#visualization-tool\">1.3. Visualization Tool</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/installation.html#install-via-anaconda\">2.1. Install via Anaconda</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/installation.html#check-for-success\">2.2. Check for Success</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/installation.html#high-version-gpu-framework-support\">2.3. High version GPU Framework support</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/installation.html#q-a\">2.4. Q &amp; A</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#datasets-overview\">3.1. Datasets Overview</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#bike-datasets\">3.2. Bike Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#bus-datasets\">3.3. Bus Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#speed-datasets\">3.4. Speed Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#pedestrian-datasets\">3.5. Pedestrian Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#taxi-datasets\">3.6. Taxi Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#metro-datasets\">3.7. Metro Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#flow-speed-datasets\">3.8. Flow Speed Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#load-uctb-dataset\">3.9. Load UCTB Dataset</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#how-to-get-the-datasets-at-other-granularities\">3.10. How to get the datasets at other granularities?</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#build-your-own-datasets\">3.11. Build your own datasets</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html#currently-supported-models\">4.1. Currently Supported Models</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html#quick-start\">4.2. Quick Start</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html#tutorial\">4.3. Tutorial</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html#advanced-features\">4.4. Advanced Features</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html#quick-start\">5.1. Quick Start</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html#contribute-to-our-project\">5.2. Contribute to our project.</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html\">6.1. UCTB.dataset package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html\">6.2. UCTB.preprocess package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html\">6.3. UCTB.model_unit package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html\">6.4. UCTB.model package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.evaluation.html\">6.5. UCTB.evaluation package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html\">6.6. UCTB.train package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.utils.html\">6.7. UCTB.utils package</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/all_results.html#datasets\">7.1. Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/all_results.html#results\">7.2. Results</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/all_results.html#implement-details\">7.3. Implement Details</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/uctb_group.html#pi\">8.1. PI</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/uctb_group.html#key-contributors\">8.2. Key Contributors</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/uctb_group.html#past-contributors\">8.3. Past Contributors</a></li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"md_file/introduction.html\" class=\"btn btn-neutral float-right\" title=\"1. Introduction\" accesskey=\"n\">Next →</a>\n      \n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/md_file/all_results.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>7. Benchmark &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"8. About us (UCTB Group)\" href=\"uctb_group.html\"/>\n        <link rel=\"prev\" title=\"6.7. UCTB.utils package\" href=\"../UCTB.utils.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">7. Benchmark</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#datasets\">7.1. Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#results\">7.2. Results</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#minute-prediction-tasks\">7.2.1. 15-minute prediction tasks</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#results-on-30-minute-prediction-tasks\">7.2.2. Results on 30-minute prediction tasks</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#results-on-60-minute-prediction-tasks\">7.2.3. Results on 60-minute prediction tasks</a></li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#implement-details\">7.3. Implement Details</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#search-space\">7.3.1. Search Space</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#bike-sharing\">7.3.2. Bike-sharing</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#ride-sharing\">7.3.3. Ride-sharing</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#metro-passenger\">7.3.4. Metro Passenger</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#electric-vehicle\">7.3.5. Electric Vehicle</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#traffic-speed\">7.3.6. Traffic Speed</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>7. Benchmark</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/all_results.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"benchmark\">\n<h1>7. Benchmark<a class=\"headerlink\" href=\"#benchmark\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"datasets\">\n<h2>7.1. Datasets<a class=\"headerlink\" href=\"#datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\">Application</th>\n<th align=\"center\">Bike-sharing</th>\n<th align=\"center\">Bike-sharing</th>\n<th align=\"center\">Bike-sharing</th>\n<th align=\"center\">Ride-sharing</th>\n<th align=\"center\">Ride-sharing</th>\n<th align=\"center\">Metro</th>\n<th align=\"center\">Metro</th>\n<th align=\"center\">EV</th>\n<th align=\"center\">Traffic Speed</th>\n<th align=\"center\">Traffic Speed</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">City</td>\n<td align=\"center\"><em>New York City</em></td>\n<td align=\"center\"><em>Chicago</em></td>\n<td align=\"center\"><em>DC</em></td>\n<td align=\"center\"><em>Xi'an</em></td>\n<td align=\"center\"><em>Chengdu</em></td>\n<td align=\"center\"><em>Chongqing</em></td>\n<td align=\"center\"><em>Shanghai</em></td>\n<td align=\"center\"><em>Beijing</em></td>\n<td align=\"center\"><em>METR-LA</em></td>\n<td align=\"center\"><em>PEMS-BAY</em></td>\n</tr>\n<tr>\n<td align=\"left\">Time span</td>\n<td align=\"center\">2013.03-2017.09</td>\n<td align=\"center\">2013.07-2017.09</td>\n<td align=\"center\">2013.07-2017.09</td>\n<td align=\"center\">2016.10-2016.11</td>\n<td align=\"center\">2016.10-2016.11</td>\n<td align=\"center\">2016.08-2017.07</td>\n<td align=\"center\">2016.07-2016.09</td>\n<td align=\"center\">2018.03-2018.05</td>\n<td align=\"center\">2012.03-2012.06</td>\n<td align=\"center\">2017.01-2017.07</td>\n</tr>\n<tr>\n<td align=\"left\">Number of riding records</td>\n<td align=\"center\">49,100,694</td>\n<td align=\"center\">13,130,969</td>\n<td align=\"center\">13,763,675</td>\n<td align=\"center\">5,922,961</td>\n<td align=\"center\">8,439,537</td>\n<td align=\"center\">409,277,117</td>\n<td align=\"center\">333,149,034</td>\n<td align=\"center\">1,272,961</td>\n<td align=\"center\">34,272</td>\n<td align=\"center\">52,128</td>\n</tr>\n<tr>\n<td align=\"left\">Number of stations</td>\n<td align=\"center\">820</td>\n<td align=\"center\">585</td>\n<td align=\"center\">532</td>\n<td align=\"center\">256</td>\n<td align=\"center\">256</td>\n<td align=\"center\">113</td>\n<td align=\"center\">288</td>\n<td align=\"center\">629</td>\n<td align=\"center\">207</td>\n<td align=\"center\">325</td>\n</tr>\n</tbody>\n</table><p>Following shows the map-visualization of stations in NYC, Chicago, DC, Xian and Chengdu.</p>\n<p><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_NYC.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_Chicago.jpg\" style=\"zoom:23%;height:800px;width:800px;\"/> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_DC.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/DiDi_Xian.jpg\" style=\"zoom:23%;height:800px;width:800px;\" />  <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/DiDi_Chengdu.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /></p>\n<p>Following shows the map-visualization of stations in Chongqing, Shanghai and Beijing, METR-LA and PEMS-BAY.</p>\n<p><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Metro_Chongqing.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Metro_Shanghai.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/EV_Beijing.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/METR_LA.png\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/PEMS_BAY.png\" style=\"zoom:23%;height:800px;width:800px;\" /></p>\n</div>\n<div class=\"section\" id=\"results\">\n<h2>7.2. Results<a class=\"headerlink\" href=\"#results\" title=\"Permalink to this headline\">¶</a></h2>\n<p>We conducted experiments on the following datasets at the granularity of 15 minutes, 30 minutes, and 60 minutes respectively. More details and conclusions can be found in the this paper.  <a class=\"reference external\" href=\"https://ieeexplore.ieee.org/document/9627543\">IEEE Xplore</a>, <a class=\"reference external\" href=\"https://arxiv.org/abs/2009.09379\">arXiv</a></p>\n<div class=\"section\" id=\"minute-prediction-tasks\">\n<h3>7.2.1. 15-minute prediction tasks<a class=\"headerlink\" href=\"#minute-prediction-tasks\" title=\"Permalink to this headline\">¶</a></h3>\n<p>The best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\"></th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n<th align=\"center\">Xi'an</th>\n<th align=\"center\">Chengdu</th>\n<th align=\"center\">Shanghai</th>\n<th align=\"center\">Chongqing</th>\n<th align=\"center\">METR-LA</th>\n<th align=\"center\">PEMS-BAY</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">HM (TC)</td>\n<td align=\"center\">1.903</td>\n<td align=\"center\">1.756</td>\n<td align=\"center\">1.655</td>\n<td align=\"center\">3.155</td>\n<td align=\"center\">4.050</td>\n<td align=\"center\">93.81</td>\n<td align=\"center\">76.67</td>\n<td align=\"center\">7.150</td>\n<td align=\"center\">2.967</td>\n</tr>\n<tr>\n<td align=\"left\">ARIMA (TC)</td>\n<td align=\"center\">1.874</td>\n<td align=\"center\">1.784</td>\n<td align=\"center\">1.689</td>\n<td align=\"center\">3.088</td>\n<td align=\"center\">3.948</td>\n<td align=\"center\">83.54</td>\n<td align=\"center\">67.11</td>\n<td align=\"center\">7.028</td>\n<td align=\"center\">2.869</td>\n</tr>\n<tr>\n<td align=\"left\">LSTM  (TC)</td>\n<td align=\"center\">1.989</td>\n<td align=\"center\">1.802</td>\n<td align=\"center\">1.678</td>\n<td align=\"center\">3.051</td>\n<td align=\"center\">3.888</td>\n<td align=\"center\">80.40</td>\n<td align=\"center\">55.37</td>\n<td align=\"center\">6.380</td>\n<td align=\"center\">2.690</td>\n</tr>\n<tr>\n<td align=\"left\">HM (TM)</td>\n<td align=\"center\">1.892</td>\n<td align=\"center\">1.668</td>\n<td align=\"center\">1.555</td>\n<td align=\"center\">2.828</td>\n<td align=\"center\">3.347</td>\n<td align=\"center\">49.75</td>\n<td align=\"center\">45.26</td>\n<td align=\"center\">8.934</td>\n<td align=\"center\">3.690</td>\n</tr>\n<tr>\n<td align=\"left\">XGBoost (TM)</td>\n<td align=\"center\">1.712</td>\n<td align=\"center\">1.672</td>\n<td align=\"center\">1.559</td>\n<td align=\"center\">2.799</td>\n<td align=\"center\">3.430</td>\n<td align=\"center\">47.89</td>\n<td align=\"center\">35.70</td>\n<td align=\"center\">6.443</td>\n<td align=\"center\">2.623</td>\n</tr>\n<tr>\n<td align=\"left\">GBRT (TM)</td>\n<td align=\"center\">1.708</td>\n<td align=\"center\">1.667</td>\n<td align=\"center\">1.552</td>\n<td align=\"center\">2.775</td>\n<td align=\"center\">3.363</td>\n<td align=\"center\">44.55</td>\n<td align=\"center\">33.29</td>\n<td align=\"center\">6.371</td>\n<td align=\"center\">2.645</td>\n</tr>\n<tr>\n<td align=\"left\">TMeta-LSTM-GAL (TM)</td>\n<td align=\"center\">1.818</td>\n<td align=\"center\">1.623</td>\n<td align=\"center\">1.540</td>\n<td align=\"center\">2.917</td>\n<td align=\"center\">3.286</td>\n<td align=\"center\">45.88</td>\n<td align=\"center\">33.34</td>\n<td align=\"center\">6.156</td>\n<td align=\"center\">2.544</td>\n</tr>\n<tr>\n<td align=\"left\">DCRNN (TC+SP)</td>\n<td align=\"center\">1.712</td>\n<td align=\"center\">1.718</td>\n<td align=\"center\">1.594</td>\n<td align=\"center\">2.889</td>\n<td align=\"center\">3.743</td>\n<td align=\"center\">56.00</td>\n<td align=\"center\">37.07</td>\n<td align=\"center\">6.440</td>\n<td align=\"center\">5.322</td>\n</tr>\n<tr>\n<td align=\"left\">STGCN (TC+SP)</td>\n<td align=\"center\">1.738</td>\n<td align=\"center\">1.806</td>\n<td align=\"center\">1.630</td>\n<td align=\"center\">2.789</td>\n<td align=\"center\">3.453</td>\n<td align=\"center\">47.40</td>\n<td align=\"center\">35.19</td>\n<td align=\"center\">6.236</td>\n<td align=\"center\">2.493</td>\n</tr>\n<tr>\n<td align=\"left\">GMAN (TC+SP)</td>\n<td align=\"center\"><strong>1.632</strong>*</td>\n<td align=\"center\"><strong>1.529</strong></td>\n<td align=\"center\"><strong>1.355</strong>*</td>\n<td align=\"center\">2.769</td>\n<td align=\"center\">3.520</td>\n<td align=\"center\">49.21</td>\n<td align=\"center\">36.66</td>\n<td align=\"center\">6.214</td>\n<td align=\"center\">3.484</td>\n</tr>\n<tr>\n<td align=\"left\">Graph-WaveNet (TC+SP+SD)</td>\n<td align=\"center\"><strong>1.644</strong></td>\n<td align=\"center\"><strong>1.460</strong>*</td>\n<td align=\"center\"><strong>1.357</strong></td>\n<td align=\"center\">2.764</td>\n<td align=\"center\">3.442</td>\n<td align=\"center\">47.84</td>\n<td align=\"center\">35.04</td>\n<td align=\"center\"><strong>5.270</strong>*</td>\n<td align=\"center\">2.780</td>\n</tr>\n<tr>\n<td align=\"left\">ST-ResNet (TM+SP)</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">2.686</td>\n<td align=\"center\">3.314</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n</tr>\n<tr>\n<td align=\"left\">ST-MGCN (TM+SM)</td>\n<td align=\"center\">1.687</td>\n<td align=\"center\">1.646</td>\n<td align=\"center\">1.545</td>\n<td align=\"center\">2.714</td>\n<td align=\"center\">3.293</td>\n<td align=\"center\">46.54</td>\n<td align=\"center\"><strong>32.72</strong></td>\n<td align=\"center\">6.645</td>\n<td align=\"center\"><strong>2.426</strong>*</td>\n</tr>\n<tr>\n<td align=\"left\">AGCRN-CDW (TM+SD)</td>\n<td align=\"center\">1.836</td>\n<td align=\"center\">1.883</td>\n<td align=\"center\">1.745</td>\n<td align=\"center\">2.722</td>\n<td align=\"center\">3.296</td>\n<td align=\"center\">77.06</td>\n<td align=\"center\">46.95</td>\n<td align=\"center\">6.709</td>\n<td align=\"center\">2.453</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-GAL (TM+SM)</td>\n<td align=\"center\">1.659</td>\n<td align=\"center\">1.607</td>\n<td align=\"center\">1.527</td>\n<td align=\"center\">2.653</td>\n<td align=\"center\"><strong>3.244</strong></td>\n<td align=\"center\"><strong>41.67</strong></td>\n<td align=\"center\"><strong>31.39</strong>*</td>\n<td align=\"center\"><strong>5.644</strong></td>\n<td align=\"center\"><strong>2.433</strong></td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-CON (TM+SM)</td>\n<td align=\"center\">1.673</td>\n<td align=\"center\">1.629</td>\n<td align=\"center\">1.512</td>\n<td align=\"center\"><strong>2.637</strong>*</td>\n<td align=\"center\"><strong>3.241</strong>*</td>\n<td align=\"center\">43.83</td>\n<td align=\"center\">38.21</td>\n<td align=\"center\">5.800</td>\n<td align=\"center\">2.449</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-DCG-GAL (TM+SM)</td>\n<td align=\"center\">1.654</td>\n<td align=\"center\">1.609</td>\n<td align=\"center\">1.517</td>\n<td align=\"center\"><strong>2.648</strong></td>\n<td align=\"center\">3.254</td>\n<td align=\"center\"><strong>40.94</strong>*</td>\n<td align=\"center\">36.90</td>\n<td align=\"center\">5.788</td>\n<td align=\"center\">2.446</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"results-on-30-minute-prediction-tasks\">\n<h3>7.2.2. Results on 30-minute prediction tasks<a class=\"headerlink\" href=\"#results-on-30-minute-prediction-tasks\" title=\"Permalink to this headline\">¶</a></h3>\n<p>The best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\"></th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n<th align=\"center\">Xi'an</th>\n<th align=\"center\">Chengdu</th>\n<th align=\"center\">Shanghai</th>\n<th align=\"center\">Chongqing</th>\n<th align=\"center\">Beijing</th>\n<th align=\"center\">METR-LA</th>\n<th align=\"center\">PEMS-BAY</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">HM (TC)</td>\n<td align=\"center\">3.206</td>\n<td align=\"center\">2.458</td>\n<td align=\"center\">2.304</td>\n<td align=\"center\">5.280</td>\n<td align=\"center\">6.969</td>\n<td align=\"center\">269.16</td>\n<td align=\"center\">221.39</td>\n<td align=\"center\">0.768</td>\n<td align=\"center\">9.471</td>\n<td align=\"center\">4.155</td>\n</tr>\n<tr>\n<td align=\"left\">ARIMA (TC)</td>\n<td align=\"center\">3.178</td>\n<td align=\"center\">2.428</td>\n<td align=\"center\">2.228</td>\n<td align=\"center\">5.035</td>\n<td align=\"center\">6.618</td>\n<td align=\"center\">212.01</td>\n<td align=\"center\">180.53</td>\n<td align=\"center\">0.755</td>\n<td align=\"center\">9.230</td>\n<td align=\"center\">3.936</td>\n</tr>\n<tr>\n<td align=\"left\">LSTM  (TC)</td>\n<td align=\"center\">3.018</td>\n<td align=\"center\">2.493</td>\n<td align=\"center\">2.212</td>\n<td align=\"center\">4.950</td>\n<td align=\"center\">6.444</td>\n<td align=\"center\">195.60</td>\n<td align=\"center\">104.61</td>\n<td align=\"center\">0.755</td>\n<td align=\"center\">7.866</td>\n<td align=\"center\">3.683</td>\n</tr>\n<tr>\n<td align=\"left\">HM (TM)</td>\n<td align=\"center\">2.686</td>\n<td align=\"center\">2.230</td>\n<td align=\"center\">1.956</td>\n<td align=\"center\">4.239</td>\n<td align=\"center\">4.851</td>\n<td align=\"center\">108.59</td>\n<td align=\"center\">74.55</td>\n<td align=\"center\">0.864</td>\n<td align=\"center\">9.560</td>\n<td align=\"center\">3.965</td>\n</tr>\n<tr>\n<td align=\"left\">XGBoost (TM)</td>\n<td align=\"center\">2.704</td>\n<td align=\"center\">2.376</td>\n<td align=\"center\">1.956</td>\n<td align=\"center\">4.172</td>\n<td align=\"center\">4.915</td>\n<td align=\"center\">81.82</td>\n<td align=\"center\">69.50</td>\n<td align=\"center\">0.686</td>\n<td align=\"center\">8.298</td>\n<td align=\"center\">3.253</td>\n</tr>\n<tr>\n<td align=\"left\">GBRT (TM)</td>\n<td align=\"center\">2.682</td>\n<td align=\"center\">2.355</td>\n<td align=\"center\">1.928</td>\n<td align=\"center\">4.135</td>\n<td align=\"center\">4.873</td>\n<td align=\"center\">83.94</td>\n<td align=\"center\">72.99</td>\n<td align=\"center\">0.689</td>\n<td align=\"center\">8.269</td>\n<td align=\"center\">3.370</td>\n</tr>\n<tr>\n<td align=\"left\">TMeta-LSTM-GAL (TM)</td>\n<td align=\"center\">2.511</td>\n<td align=\"center\"><strong>2.133</strong>*</td>\n<td align=\"center\">1.927</td>\n<td align=\"center\">3.847</td>\n<td align=\"center\">4.678</td>\n<td align=\"center\">85.19</td>\n<td align=\"center\">53.18</td>\n<td align=\"center\">0.686</td>\n<td align=\"center\">7.436</td>\n<td align=\"center\">3.231</td>\n</tr>\n<tr>\n<td align=\"left\">DCRNN (TC+SP)</td>\n<td align=\"center\">2.618</td>\n<td align=\"center\">2.246</td>\n<td align=\"center\">2.118</td>\n<td align=\"center\">4.529</td>\n<td align=\"center\">6.258</td>\n<td align=\"center\">116.15</td>\n<td align=\"center\">65.72</td>\n<td align=\"center\">0.757</td>\n<td align=\"center\">8.562</td>\n<td align=\"center\">6.198</td>\n</tr>\n<tr>\n<td align=\"left\">STGCN (TC+SP)</td>\n<td align=\"center\">2.841</td>\n<td align=\"center\">2.482</td>\n<td align=\"center\">2.067</td>\n<td align=\"center\">3.992</td>\n<td align=\"center\">5.051</td>\n<td align=\"center\">91.29</td>\n<td align=\"center\">58.34</td>\n<td align=\"center\">0.694</td>\n<td align=\"center\">7.871</td>\n<td align=\"center\">3.136</td>\n</tr>\n<tr>\n<td align=\"left\">GMAN (TC+SP)</td>\n<td align=\"center\">2.792</td>\n<td align=\"center\">2.336</td>\n<td align=\"center\"><strong>1.836</strong>*</td>\n<td align=\"center\">4.026</td>\n<td align=\"center\">5.293</td>\n<td align=\"center\">97.58</td>\n<td align=\"center\">51.37</td>\n<td align=\"center\">0.764</td>\n<td align=\"center\">7.276</td>\n<td align=\"center\">3.688</td>\n</tr>\n<tr>\n<td align=\"left\">Graph-WaveNet (TC+SP+SD)</td>\n<td align=\"center\">2.666</td>\n<td align=\"center\">2.158</td>\n<td align=\"center\">1.874</td>\n<td align=\"center\">3.986</td>\n<td align=\"center\">5.097</td>\n<td align=\"center\">92.88</td>\n<td align=\"center\">52.52</td>\n<td align=\"center\">0.719</td>\n<td align=\"center\"><strong>6.809</strong>*</td>\n<td align=\"center\">3.589</td>\n</tr>\n<tr>\n<td align=\"left\">ST-ResNet (TM+SP)</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">3.903</td>\n<td align=\"center\">4.673</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n</tr>\n<tr>\n<td align=\"left\">ST-MGCN (TM+SM)</td>\n<td align=\"center\">2.513</td>\n<td align=\"center\">2.177</td>\n<td align=\"center\">1.903</td>\n<td align=\"center\">3.886</td>\n<td align=\"center\">4.732</td>\n<td align=\"center\">88.76</td>\n<td align=\"center\">50.96</td>\n<td align=\"center\">0.691</td>\n<td align=\"center\">8.079</td>\n<td align=\"center\"><strong>3.042</strong></td>\n</tr>\n<tr>\n<td align=\"left\">AGCRN-CDW (TM+SD)</td>\n<td align=\"center\">2.830</td>\n<td align=\"center\">2.565</td>\n<td align=\"center\">2.074</td>\n<td align=\"center\">3.958</td>\n<td align=\"center\">4.753</td>\n<td align=\"center\">238.99</td>\n<td align=\"center\">131.55</td>\n<td align=\"center\">0.688</td>\n<td align=\"center\">8.575</td>\n<td align=\"center\"><strong>3.022</strong>*</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-GAL (TM+SM)</td>\n<td align=\"center\"><strong>2.410</strong>*</td>\n<td align=\"center\">2.170</td>\n<td align=\"center\">1.856</td>\n<td align=\"center\"><strong>3.808</strong></td>\n<td align=\"center\">4.650</td>\n<td align=\"center\"><strong>75.36</strong>*</td>\n<td align=\"center\"><strong>49.47</strong></td>\n<td align=\"center\"><strong>0.670</strong></td>\n<td align=\"center\">7.156</td>\n<td align=\"center\">3.116</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-CON (TM+SM)</td>\n<td align=\"center\"><strong>2.411</strong></td>\n<td align=\"center\"><strong>2.133</strong>*</td>\n<td align=\"center\">1.859</td>\n<td align=\"center\"><strong>3.772</strong>*</td>\n<td align=\"center\"><strong>4.613</strong>*</td>\n<td align=\"center\">80.69</td>\n<td align=\"center\">50.01</td>\n<td align=\"center\"><strong>0.667</strong>*</td>\n<td align=\"center\"><strong>6.889</strong>*</td>\n<td align=\"center\">3.204</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-DCG-GAL (TM+SM)</td>\n<td align=\"center\"><strong>2.411</strong></td>\n<td align=\"center\">2.182</td>\n<td align=\"center\"><strong>1.852</strong></td>\n<td align=\"center\">3.833</td>\n<td align=\"center\"><strong>4.635</strong></td>\n<td align=\"center\"><strong>77.49</strong></td>\n<td align=\"center\"><strong>48.96</strong>*</td>\n<td align=\"center\"><strong>0.670</strong></td>\n<td align=\"center\">7.184</td>\n<td align=\"center\">3.187</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"results-on-60-minute-prediction-tasks\">\n<h3>7.2.3. Results on 60-minute prediction tasks<a class=\"headerlink\" href=\"#results-on-60-minute-prediction-tasks\" title=\"Permalink to this headline\">¶</a></h3>\n<p>The best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\"></th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n<th align=\"center\">Xi'an</th>\n<th align=\"center\">Chengdu</th>\n<th align=\"center\">Shanghai</th>\n<th align=\"center\">Chongqing</th>\n<th align=\"center\">Beijing</th>\n<th align=\"center\">METR-LA</th>\n<th align=\"center\">PEMS-BAY</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">HM (TC)</td>\n<td align=\"center\">5.814</td>\n<td align=\"center\">4.143</td>\n<td align=\"center\">3.485</td>\n<td align=\"center\">10.136</td>\n<td align=\"center\">14.145</td>\n<td align=\"center\">824.94</td>\n<td align=\"center\">673.55</td>\n<td align=\"center\">1.178</td>\n<td align=\"center\">12.303</td>\n<td align=\"center\">5.779</td>\n</tr>\n<tr>\n<td align=\"left\">ARIMA (TC)</td>\n<td align=\"center\">5.289</td>\n<td align=\"center\">3.744</td>\n<td align=\"center\">3.183</td>\n<td align=\"center\">9.475</td>\n<td align=\"center\">13.259</td>\n<td align=\"center\">676.79</td>\n<td align=\"center\">578.19</td>\n<td align=\"center\">0.982</td>\n<td align=\"center\">11.739</td>\n<td align=\"center\">5.670</td>\n</tr>\n<tr>\n<td align=\"left\">LSTM  (TC)</td>\n<td align=\"center\">5.167</td>\n<td align=\"center\">3.721</td>\n<td align=\"center\">3.234</td>\n<td align=\"center\">9.830</td>\n<td align=\"center\">13.483</td>\n<td align=\"center\">506.07</td>\n<td align=\"center\">322.81</td>\n<td align=\"center\">0.999</td>\n<td align=\"center\">10.083</td>\n<td align=\"center\">4.777</td>\n</tr>\n<tr>\n<td align=\"left\">HM (TM)</td>\n<td align=\"center\">3.992</td>\n<td align=\"center\">3.104</td>\n<td align=\"center\">2.632</td>\n<td align=\"center\">6.186</td>\n<td align=\"center\">7.512</td>\n<td align=\"center\">172.55</td>\n<td align=\"center\">119.86</td>\n<td align=\"center\">1.016</td>\n<td align=\"center\">10.727</td>\n<td align=\"center\">4.018</td>\n</tr>\n<tr>\n<td align=\"left\">XGBoost (TM)</td>\n<td align=\"center\">4.102</td>\n<td align=\"center\">3.003</td>\n<td align=\"center\">2.643</td>\n<td align=\"center\">6.733</td>\n<td align=\"center\">7.592</td>\n<td align=\"center\">160.38</td>\n<td align=\"center\">117.05</td>\n<td align=\"center\">0.834</td>\n<td align=\"center\">10.299</td>\n<td align=\"center\">3.703</td>\n</tr>\n<tr>\n<td align=\"left\">GBRT (TM)</td>\n<td align=\"center\">4.039</td>\n<td align=\"center\">2.984</td>\n<td align=\"center\">2.611</td>\n<td align=\"center\">6.446</td>\n<td align=\"center\">7.511</td>\n<td align=\"center\">154.29</td>\n<td align=\"center\">113.92</td>\n<td align=\"center\">0.828</td>\n<td align=\"center\">10.013</td>\n<td align=\"center\">3.704</td>\n</tr>\n<tr>\n<td align=\"left\">TMeta-LSTM-GAL (TM)</td>\n<td align=\"center\">3.739</td>\n<td align=\"center\">2.840</td>\n<td align=\"center\">2.557</td>\n<td align=\"center\"><strong>5.843</strong></td>\n<td align=\"center\">6.949</td>\n<td align=\"center\">163.31</td>\n<td align=\"center\">102.86</td>\n<td align=\"center\">0.840</td>\n<td align=\"center\"><strong>8.670</strong>*</td>\n<td align=\"center\">3.616</td>\n</tr>\n<tr>\n<td align=\"left\">DCRNN (TC+SP)</td>\n<td align=\"center\">4.187</td>\n<td align=\"center\">3.081</td>\n<td align=\"center\">3.016</td>\n<td align=\"center\">8.203</td>\n<td align=\"center\">11.444</td>\n<td align=\"center\">340.25</td>\n<td align=\"center\">122.31</td>\n<td align=\"center\">0.989</td>\n<td align=\"center\">11.121</td>\n<td align=\"center\">6.920</td>\n</tr>\n<tr>\n<td align=\"left\">STGCN (TC+SP)</td>\n<td align=\"center\">3.895</td>\n<td align=\"center\">2.989</td>\n<td align=\"center\">2.597</td>\n<td align=\"center\">6.150</td>\n<td align=\"center\">7.710</td>\n<td align=\"center\">187.98</td>\n<td align=\"center\">106.16</td>\n<td align=\"center\">0.859</td>\n<td align=\"center\">10.688</td>\n<td align=\"center\">3.472</td>\n</tr>\n<tr>\n<td align=\"left\">GMAN (TC+SP)</td>\n<td align=\"center\">4.251</td>\n<td align=\"center\">2.875</td>\n<td align=\"center\">2.530</td>\n<td align=\"center\">7.099</td>\n<td align=\"center\">13.351</td>\n<td align=\"center\">193.39</td>\n<td align=\"center\">117.52</td>\n<td align=\"center\">0.949</td>\n<td align=\"center\">10.012</td>\n<td align=\"center\">3.846</td>\n</tr>\n<tr>\n<td align=\"left\">Graph-WaveNet (TC+SP+SD)</td>\n<td align=\"center\">3.863</td>\n<td align=\"center\">2.812</td>\n<td align=\"center\"><strong>2.403</strong>*</td>\n<td align=\"center\">6.541</td>\n<td align=\"center\">8.162</td>\n<td align=\"center\">186.82</td>\n<td align=\"center\">102.75</td>\n<td align=\"center\">0.930</td>\n<td align=\"center\">9.463</td>\n<td align=\"center\">4.135</td>\n</tr>\n<tr>\n<td align=\"left\">ST-ResNet (TM+SP)</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">6.075</td>\n<td align=\"center\">7.155</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n</tr>\n<tr>\n<td align=\"left\">ST-MGCN (TM+SM)</td>\n<td align=\"center\">3.723</td>\n<td align=\"center\">2.904</td>\n<td align=\"center\">2.518</td>\n<td align=\"center\">5.878</td>\n<td align=\"center\">7.067</td>\n<td align=\"center\">159.52</td>\n<td align=\"center\">104.87</td>\n<td align=\"center\">0.827</td>\n<td align=\"center\">10.798</td>\n<td align=\"center\"><strong>3.486</strong></td>\n</tr>\n<tr>\n<td align=\"left\">AGCRN-CDW (TM+SD)</td>\n<td align=\"center\">3.795</td>\n<td align=\"center\">2.935</td>\n<td align=\"center\">2.580</td>\n<td align=\"center\">8.835</td>\n<td align=\"center\">10.275</td>\n<td align=\"center\">658.12</td>\n<td align=\"center\">287.41</td>\n<td align=\"center\">0.844</td>\n<td align=\"center\">10.728</td>\n<td align=\"center\"><strong>3.381</strong>*</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-GAL (TM+SM)</td>\n<td align=\"center\"><strong>3.518</strong></td>\n<td align=\"center\"><strong>2.695</strong></td>\n<td align=\"center\">2.405</td>\n<td align=\"center\">5.871</td>\n<td align=\"center\"><strong>6.858</strong>*</td>\n<td align=\"center\">153.17</td>\n<td align=\"center\"><strong>97.87</strong></td>\n<td align=\"center\">0.831</td>\n<td align=\"center\"><strong>8.834</strong></td>\n<td align=\"center\">3.514</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-CON (TM+SM)</td>\n<td align=\"center\"><strong>3.507</strong>*</td>\n<td align=\"center\">2.739</td>\n<td align=\"center\"><strong>2.404</strong></td>\n<td align=\"center\"><strong>5.829</strong>*</td>\n<td align=\"center\"><strong>6.873</strong></td>\n<td align=\"center\"><strong>149.05</strong></td>\n<td align=\"center\">106.41</td>\n<td align=\"center\"><strong>0.807</strong></td>\n<td align=\"center\">9.147</td>\n<td align=\"center\">3.552</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-DCG-GAL (TM+SM)</td>\n<td align=\"center\">3.521</td>\n<td align=\"center\"><strong>2.652</strong>*</td>\n<td align=\"center\">2.423</td>\n<td align=\"center\">5.908</td>\n<td align=\"center\">6.904</td>\n<td align=\"center\"><strong>143.18</strong>*</td>\n<td align=\"center\"><strong>94.78</strong>*</td>\n<td align=\"center\"><strong>0.803</strong>*</td>\n<td align=\"center\">8.993</td>\n<td align=\"center\">3.500</td>\n</tr>\n</tbody>\n</table></div>\n</div>\n<div class=\"section\" id=\"implement-details\">\n<h2>7.3. Implement Details<a class=\"headerlink\" href=\"#implement-details\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"search-space\">\n<h3>7.3.1. Search Space<a class=\"headerlink\" href=\"#search-space\" title=\"Permalink to this headline\">¶</a></h3>\n<p>We use <a class=\"reference external\" href=\"https://github.com/microsoft/nni\">nni</a> toolkit to search the best parameters of HM, XGBoost and GBRT model. Search space are following.</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">Model</th>\n<th align=\"center\">Search Space</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>CT: 0~6</code>, <code>PT: 0~7</code>, <code>TT: 0~4</code></td>\n</tr>\n<tr>\n<td align=\"center\">ARIMA</td>\n<td align=\"center\"><code>CT:168</code>,<code>p:3</code>, <code>d:0</code>, <code>q:0</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>CT: 0~12</code>, <code>PT: 0~14</code>, <code>TT: 0~4</code>, <code>estimater: 10~200</code>, <code>depth: 2~10</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>CT: 0~12</code>, <code>PT: 0~14</code>, <code>TT: 0~4</code>, <code>estimater: 10~200</code>, <code>depth: 2~10</code></td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"bike-sharing\">\n<h3>7.3.2. Bike-sharing<a class=\"headerlink\" href=\"#bike-sharing\" title=\"Permalink to this headline\">¶</a></h3>\n<ul class=\"simple\">\n<li>HM &amp; XGBoost &amp; GBRT</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">15 minutes</th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>3-1-2</code></td>\n<td align=\"center\"><code>5-0-4</code></td>\n<td align=\"center\"><code>3-7-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>8-14-4-32-2</code></td>\n<td align=\"center\"><code>11-13-4-28-2</code></td>\n<td align=\"center\"><code>4-14-4-27-2</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>7-13-4-144-1</code></td>\n<td align=\"center\"><code>7-15-4-101-2</code></td>\n<td align=\"center\"><code>8-11-5-101-2</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">30 minutes</th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-1-2</code></td>\n<td align=\"center\"><code>3-2-1</code></td>\n<td align=\"center\"><code>3-1-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>12-8-1-36-3</code></td>\n<td align=\"center\"><code>7-5-2-24-2</code></td>\n<td align=\"center\"><code>12-13-4-27-2</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>12-10-0-72-4</code></td>\n<td align=\"center\"><code>9-13-2-91-2</code></td>\n<td align=\"center\"><code>13-15-5-140-1</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">60 minutes</th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>1-1-3</code></td>\n<td align=\"center\"><code>1-1-1</code></td>\n<td align=\"center\"><code>2-1-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>13-7-0-103-3</code></td>\n<td align=\"center\"><code>11-8-0-35-4</code></td>\n<td align=\"center\"><code>11-9-5-28-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>12-6-1-58-5</code></td>\n<td align=\"center\"><code>11-8-1-92-5</code></td>\n<td align=\"center\"><code>11-8-5-54-3</code></td>\n</tr>\n</tbody>\n</table><ul>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/bike_trial.py\">ST_MGCN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/bike_trial.py\">DCRNN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\">LSTM &amp; TMeta-LSTM-GAL &amp; STMeta-V1  &amp; STMeta-V2  &amp; STMeta-V3</p>\n<p>These five models can be run by specifying data files and model files on  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py\">STMeta_Obj.py</a>.</p>\n<p>Data Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_nyc.data.yml\">bike_nyc.data.yml</a> , <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_chicago.data.yml\">bike_chicago.data.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_dc.data.yml\">bike_dc.data.yml</a></p>\n<p>Model Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml\">STMeta_v0.model.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml\">STMeta_v1.model.yml</a>.,  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml\">STMeta_v2.model.yml</a>., <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml\">STMeta_v3.model.yml</a>.</p>\n<ul class=\"simple\">\n<li>LSTM</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<ul class=\"simple\">\n<li>TMeta-LSTM-GAL</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<ul class=\"simple\">\n<li>STMeta-V1</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<ul class=\"simple\">\n<li>STMeta-V2</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<ul class=\"simple\">\n<li>STMeta-V3</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"ride-sharing\">\n<h3>7.3.3. Ride-sharing<a class=\"headerlink\" href=\"#ride-sharing\" title=\"Permalink to this headline\">¶</a></h3>\n<ul class=\"simple\">\n<li>HM &amp; XGBoost &amp; GBRT</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">15 minutes</th>\n<th align=\"center\"><strong>Xi'an</strong></th>\n<th align=\"center\"><strong>Chengdu</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>5-0-4</code></td>\n<td align=\"center\"><code>2-7-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>7-14-0-10-4</code></td>\n<td align=\"center\"><code>12-14-1-27-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>11-2-2-45-3</code></td>\n<td align=\"center\"><code>13-15-5-39-3</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">30 minutes</th>\n<th align=\"center\"><strong>Xi'an</strong></th>\n<th align=\"center\"><strong>Chengdu</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-0-2</code></td>\n<td align=\"center\"><code>1-7-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>9-0-2-25-3</code></td>\n<td align=\"center\"><code>9-14-3-16-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>9-0-2-80-3</code></td>\n<td align=\"center\"><code>10-10-5-34-3</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">60 minutes</th>\n<th align=\"center\"><strong>Xi'an</strong></th>\n<th align=\"center\"><strong>Chengdu</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>1-1-2</code></td>\n<td align=\"center\"><code>0-7-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>12-0-2-10-5</code></td>\n<td align=\"center\"><code>9-6-2-14-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>9-0-2-50-2</code></td>\n<td align=\"center\"><code>9-12-2-50-5</code></td>\n</tr>\n</tbody>\n</table><ul class=\"simple\">\n<li>ST-ResNet</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">ST-ResNet Search Space</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\"><code>residual_units:2~6</code>,  <code>conv_filter:[32, 64, 128]</code>,  <code>kernal_size:3~5</code>, <br /><code>lr:[0.0001, 0.00002, 0.00004, 0.00008, 0.00001]</code>, <code>batch_size:[32, 64, 128, 256]</code></td>\n</tr>\n</tbody>\n</table><p>The best parameters found are following.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">args</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n  <span class=\"s1\">&#39;dataset&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;DiDi&#39;</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;city&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Chengdu&#39;</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;num_residual_unit&#39;</span><span class=\"p\">:</span> <span class=\"mi\">4</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;conv_filters&#39;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;kernel_size&#39;</span><span class=\"p\">:</span> <span class=\"mi\">3</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;lr&#39;</span><span class=\"p\">:</span> <span class=\"mf\">1e-5</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;batch_size&#39;</span><span class=\"p\">:</span> <span class=\"mi\">32</span>\n</pre></div>\n</div>\n<p>We can modify <code class=\"docutils literal\"><span class=\"pre\">city</span></code> parameter to <code class=\"docutils literal\"><span class=\"pre\">Chengdu</span></code> or <code class=\"docutils literal\"><span class=\"pre\">Xian</span></code> in <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_ResNet/ST_ResNet.py\">ST_ResNet.py</a> , and then run it.</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span> python ST_ResNet.py \n</pre></div>\n</div>\n<ul>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/didi_trial.py\">ST_MGCN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/didi_trial.py\">DCRNN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\">LSTM &amp; TMeta-LSTM-GAL &amp; STMeta-V1  &amp; STMeta-V2  &amp; STMeta-V3</p>\n<p>These five models can be run by specifying data files and model files on <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py\">STMeta_Obj.py</a>.</p>\n<p>Data Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_xian.data.yml\">didi_xian.data.yml</a> , <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_chengdu.data.yml\">didi_chengdu.data.yml</a>.</p>\n<p>Model Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml\">STMeta_v0.model.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml\">STMeta_v1.model.yml</a>.,  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml\">STMeta_v2.model.yml</a>., <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml\">STMeta_v3.model.yml</a>.</p>\n<ul>\n<li><p class=\"first\">LSTM</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml&#39;</span>\n        <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml&#39;</span>\n        <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">TMeta-LSTM-GAL</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V1</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V2</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V3</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"metro-passenger\">\n<h3>7.3.4. Metro Passenger<a class=\"headerlink\" href=\"#metro-passenger\" title=\"Permalink to this headline\">¶</a></h3>\n<ul class=\"simple\">\n<li>HM &amp; XGBoost &amp; GBRT</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">15 minutes</th>\n<th align=\"center\"><strong>Chongqing</strong></th>\n<th align=\"center\"><strong>Shanghai</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-1-4</code></td>\n<td align=\"center\"><code>1-0-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>12-6-4-51-8</code></td>\n<td align=\"center\"><code>11-10-4-31-7</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>12-14-1-182-7</code></td>\n<td align=\"center\"><code>12-7-1-148-5</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">30 minutes</th>\n<th align=\"center\"><strong>Chongqing</strong></th>\n<th align=\"center\"><strong>Shanghai</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>1-0-4</code></td>\n<td align=\"center\"><code>1-1-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>11-5-0-45-8</code></td>\n<td align=\"center\"><code>12-6-1-206-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>10-3-0-107-8</code></td>\n<td align=\"center\"><code>7-4-1-58-7</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">60 minutes</th>\n<th align=\"center\"><strong>Chongqing</strong></th>\n<th align=\"center\"><strong>Shanghai</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>0-1-4</code></td>\n<td align=\"center\"><code>0-0-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>9-14-2-200-5</code></td>\n<td align=\"center\"><code>3-7-0-50-5</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>12-10-4-200-5</code></td>\n<td align=\"center\"><code>9-5-1-66-6</code></td>\n</tr>\n</tbody>\n</table><ul>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metro_trial.py\">ST_MGCN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metro_trial.py\">DCRNN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\">LSTM &amp; TMeta-LSTM-GAL &amp; STMeta-V1  &amp; STMeta-V2  &amp; STMeta-V3</p>\n<p>These five models can be run by specifying data files and model files on <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py\">STMeta_Obj.py</a>.</p>\n<p>Data Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_chongqing.data.yml\">metro_chongqing.data.yml</a> , <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_shanghai.data.yml\">metro_shanghai.data.yml</a>.</p>\n<p>Model Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml\">STMeta_v0.model.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml\">STMeta_v1.model.yml</a>.,  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml\">STMeta_v2.model.yml</a>., <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml\">STMeta_v3.model.yml</a>.</p>\n<ul>\n<li><p class=\"first\">LSTM</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">TMeta-LSTM-GAL</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V1</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V2</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V3</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml &#39;</span>\n        <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"electric-vehicle\">\n<h3>7.3.5. Electric Vehicle<a class=\"headerlink\" href=\"#electric-vehicle\" title=\"Permalink to this headline\">¶</a></h3>\n<ul class=\"simple\">\n<li>HM &amp; XGBoost &amp; GBRT</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">Beijing</th>\n<th align=\"center\">30 minutes</th>\n<th align=\"center\">60 minutes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-0-0</code></td>\n<td align=\"center\"><code>2-0-2</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>6-6-1-19-2</code></td>\n<td align=\"center\"><code>12-7-0-20-2</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>13-3-2-47-3</code></td>\n<td align=\"center\"><code>12-10-0-100-2</code></td>\n</tr>\n</tbody>\n</table><ul>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/cs_trial.py\">ST_MGCN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/cs_trial.py\">DCRNN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\">LSTM &amp; TMeta-LSTM-GAL &amp; STMeta-V1  &amp; STMeta-V2  &amp; STMeta-V3</p>\n<p>These five models can be run by specifying data files and model files on <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py\">STMeta_Obj.py</a>.</p>\n<p>Data Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/chargestation_beijing.data.yml\">chargestation_beijing.data.yml</a>.</p>\n<p>Model Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml\">STMeta_v0.model.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml\">STMeta_v1.model.yml</a>.,  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml\">STMeta_v2.model.yml</a>., <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml\">STMeta_v3.model.yml</a>.</p>\n<ul>\n<li><p class=\"first\">LSTM</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:2&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">TMeta-LSTM-GAL</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:1&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:2&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V1</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n        <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V2</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n        <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V3</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"traffic-speed\">\n<h3>7.3.6. Traffic Speed<a class=\"headerlink\" href=\"#traffic-speed\" title=\"Permalink to this headline\">¶</a></h3>\n<ul class=\"simple\">\n<li>HM &amp; XGBoost &amp; GBRT</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">15 minutes</th>\n<th align=\"center\"><strong>METR-LA</strong></th>\n<th align=\"center\"><strong>PEMS-BAY</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-0-4</code></td>\n<td align=\"center\"><code>1-0-1</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>11-1-2-25-3</code></td>\n<td align=\"center\"><code>12-4-2-21-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>11-8-2-29-4</code></td>\n<td align=\"center\"><code>10-6-1-65-6</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">30 minutes</th>\n<th align=\"center\"><strong>METR-LA</strong></th>\n<th align=\"center\"><strong>PEMS-BAY</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-0-4</code></td>\n<td align=\"center\"><code>1-0-1</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>6-6-0-25-3</code></td>\n<td align=\"center\"><code>12-13-2-27-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>10-0-0-27-3</code></td>\n<td align=\"center\"><code>12-6-2-90-7</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">60 minutes</th>\n<th align=\"center\"><strong>METR-LA</strong></th>\n<th align=\"center\"><strong>PEMS-BAY</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-1-4</code></td>\n<td align=\"center\"><code>1-1-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>2-2-0-25-3</code></td>\n<td align=\"center\"><code>12-6-2-19-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>4-5-1-19-4</code></td>\n<td align=\"center\"><code>12-7-2-59-5</code></td>\n</tr>\n</tbody>\n</table><ul>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metr_trial.py\">METR-LA</a>  and <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/pems_trial.py\">PEMS-BAY</a>  ST_MGCN Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metr_trial.py\">METR-LA</a> and <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/pems_trial.py\">PEMS-BAY</a> DCRNN Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\">LSTM &amp; TMeta-LSTM-GAL &amp; STMeta-V1  &amp; STMeta-V2  &amp; STMeta-V3</p>\n<p>These five models can be run by specifying data files and model files on <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py\">STMeta_Obj.py</a>.</p>\n<p>Data Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metr_la.data.yml\">metr_la.data.yml</a> , <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/pems_bay.data.yml\">pems_bay.data.yml</a>.</p>\n<p>Model Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml\">STMeta_v0.model.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml\">STMeta_v1.model.yml</a>.,  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml\">STMeta_v2.model.yml</a>., <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml\">STMeta_v3.model.yml</a>.</p>\n<ul>\n<li><p class=\"first\">LSTM</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">TMeta-LSTM-GAL</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V1</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V2</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V3</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"uctb_group.html\" class=\"btn btn-neutral float-right\" title=\"8. About us (UCTB Group)\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"../UCTB.utils.html\" class=\"btn btn-neutral\" title=\"6.7. UCTB.utils package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/md_file/installation.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>2. Installation &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"3. Urban Datasets\" href=\"urban_dataset.html\"/>\n        <link rel=\"prev\" title=\"1. Introduction\" href=\"introduction.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">2. Installation</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#install-via-anaconda\">2.1. Install via Anaconda</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#check-for-success\">2.2. Check for Success</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#high-version-gpu-framework-support\">2.3. High version GPU Framework support</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#q-a\">2.4. Q &amp; A</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>2. Installation</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/installation.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"installation\">\n<h1>2. Installation<a class=\"headerlink\" href=\"#installation\" title=\"Permalink to this headline\">¶</a></h1>\n<p>UCTB is based on several well-known deep learning frameworks, including <strong>PyTorch</strong>, <strong>TensorFlow</strong>, and <strong>MXNet</strong>. If you have an Nvidia GPU installed on your computer, we highly recommend you install the GPU version of these frameworks.</p>\n<p>UCTB toolbox may not work successfully with the upgrade of some packages. We thus encourage you to use the specific version of packages to avoid unseen errors. <em><strong>To avoid potential conflict, we highly recommend you install UCTB vis Anaconda.</strong></em></p>\n<div class=\"section\" id=\"install-via-anaconda\">\n<h2>2.1. Install via Anaconda<a class=\"headerlink\" href=\"#install-via-anaconda\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Step 1: Install Anaconda</strong></p>\n<p>You can skip to step 2 if you already installed Anaconda.</p>\n<p>To install Anaconda, please refer to this page <a class=\"reference external\" href=\"https://www.anaconda.com/download\">https://www.anaconda.com/download</a>.</p>\n<p><strong>Step 2: create UCTB environment</strong></p>\n<p>Create the UCTB environment by the following command. You may need the <a class=\"reference external\" href=\"https://github.com/uctb/UCTB/blob/master/environment.yaml\">environment.yaml</a> file.</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span>conda env create -f environment.yaml\n</pre></div>\n</div>\n<p>Then activate the UCTB environment and start to use it. 🎉🎉🎉</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span>conda activate UCTB\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"check-for-success\">\n<h2>2.2. Check for Success<a class=\"headerlink\" href=\"#check-for-success\" title=\"Permalink to this headline\">¶</a></h2>\n<p>If you  successfully install UCTB, you may get the following output after importing UCTB.</p>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span>(UCTB) XXX:~$ python\nType &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.\n&gt;&gt;&gt; import UCTB\nUsing TensorFlow backend.\n&gt;&gt;&gt; \n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"high-version-gpu-framework-support\">\n<h2>2.3. High version GPU Framework support<a class=\"headerlink\" href=\"#high-version-gpu-framework-support\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Existing Problems</strong></p>\n<p>Due to changes in the design architecture of high-version GPUs, low-version CUDA is not compatible with high-version GPUs. As a result, Tensorflow 1.x is only compatible with low-version CUDA, leading to runtime failures on machines equipped with high-version GPUs. https://stackoverflow.com/questions/50622525/which-tensorflow-and-cuda-version-combinations-are-compatible</p>\n<p><strong>Solution</strong></p>\n<p>Thanks to the <a class=\"reference external\" href=\"https://github.com/NVIDIA/tensorflow\">Nvidia TensorFlow</a> project, which was created to support newer hardware and improve libraries for NVIDIA GPU users using TensorFlow 1.x, we can now install UCTB on machines with newer GPUs. You can follow the installation tutorial below to start enjoying UCTB.</p>\n<p><strong>Clone the project</strong></p>\n<div class=\"highlight-sh\"><div class=\"highlight\"><pre><span></span>&gt;&gt;&gt; git clone git@github.com:uctb/UCTB.git\n&gt;&gt;&gt; <span class=\"nb\">cd</span> UCTB\n</pre></div>\n</div>\n<p><strong>Create Anaconda Environment</strong></p>\n<div class=\"highlight-sh\"><div class=\"highlight\"><pre><span></span>&gt;&gt;&gt; conda create -n UCTB <span class=\"nv\">python</span><span class=\"o\">=</span><span class=\"m\">3</span>.8\n&gt;&gt;&gt; conda activate UCTB\n</pre></div>\n</div>\n<p><strong>Install Nvidia Tensorflow</strong></p>\n<div class=\"highlight-sh\"><div class=\"highlight\"><pre><span></span>&gt;&gt;&gt; pip install --user nvidia-pyindex\n&gt;&gt;&gt; pip install --user nvidia-tensorflow<span class=\"o\">[</span>horovod<span class=\"o\">]</span>\n</pre></div>\n</div>\n<p><strong>Install UCTB from Source</strong></p>\n<div class=\"highlight-sh\"><div class=\"highlight\"><pre><span></span>&gt;&gt;&gt; python build_install.py\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"q-a\">\n<h2>2.4. Q &amp; A<a class=\"headerlink\" href=\"#q-a\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Q: I fail to install PyTorch, TensorFlow, and MXNet, what is the version number of them?</strong></p>\n<p>A: We recommend you install PyTorch==1.1.0, TensorFlow==1.13.1, and MXNet==1.5.0 with cuda version 10.0. We here give the installation command:</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># Install PyTorch</span>\nconda install <span class=\"nv\">pytorch</span><span class=\"o\">==</span><span class=\"m\">1</span>.1.0 <span class=\"nv\">torchvision</span><span class=\"o\">==</span><span class=\"m\">0</span>.3.0 <span class=\"nv\">cudatoolkit</span><span class=\"o\">=</span><span class=\"m\">10</span>.0 -c pytorch\n\n<span class=\"c1\"># Install TensorFlow</span>\nconda install tensorflow-gpu<span class=\"o\">==</span><span class=\"m\">1</span>.13.1\n\n<span class=\"c1\"># Install MXNet</span>\npip install mxnet-cu100<span class=\"o\">==</span><span class=\"m\">1</span>.5.0\n</pre></div>\n</div>\n<p><strong>Q:  I'm using Windows OS, and my Anaconda reports that it cannot find the PyTorch 1.1.0 packages. How to install it?</strong></p>\n<p>A: You could install it by the following command.</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span>pip install <span class=\"nv\">torch</span><span class=\"o\">==</span><span class=\"m\">1</span>.1.0 <span class=\"nv\">torchvision</span><span class=\"o\">==</span><span class=\"m\">0</span>.3.0 -f https://download.pytorch.org/whl/cu100/torch_stable.html\n</pre></div>\n</div>\n<p><strong>Q:  I fail to install UCTB via pip. How to install it ?</strong></p>\n<p>A: This situation may occur when your OS is Windows. You could install UCTB by its source code. First download UCTB's source code and your folder may look like this:</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span>XXX/UCTB-master# ls\nbuild_install.py  dist  environment.yaml  __init__.py  QuickStarts  setup.py\nbuild.py          docs  Experiments       LICENSE      README.md    UCTB\n</pre></div>\n</div>\n<p>then build and install UCTB by the following command:</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span>python build_install.py\n</pre></div>\n</div>\n<p><u><a class=\"reference external\" href=\"../index.html\">Back To HomePage</a></u></p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"urban_dataset.html\" class=\"btn btn-neutral float-right\" title=\"3. Urban Datasets\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"introduction.html\" class=\"btn btn-neutral\" title=\"1. Introduction\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/md_file/introduction.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>1. Introduction &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"2. Installation\" href=\"installation.html\"/>\n        <link rel=\"prev\" title=\"Welcome to UCTB’s documentation!\" href=\"../index.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">1. Introduction</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#urban-datasts\">1.1. Urban Datasts</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#predictive-tool\">1.2. Predictive Tool</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#visualization-tool\">1.3. Visualization Tool</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>1. Introduction</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/introduction.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"introduction\">\n<h1>1. Introduction<a class=\"headerlink\" href=\"#introduction\" title=\"Permalink to this headline\">¶</a></h1>\n<p><strong>Urban Computing Tool Box</strong> is a package providing <a class=\"reference external\" href=\"https://github.com/uctb/Urban-Dataset\"><strong>urban datasets</strong></a>, <a class=\"reference external\" href=\"https://github.com/uctb/UCTB\"><strong>spatial-temporal prediction models</strong></a>, and <a class=\"reference external\" href=\"https://github.com/uctb/visualization-tool-UCTB\"><strong>visualization tools</strong></a> for various urban computing tasks, such as traffic prediction, crowd flow prediction, ridesharing demand prediction, etc.</p>\n<p>UCTB is a flexible and open package. You can use the data we provided or use your data, and the data structure is well stated in the <a class=\"reference external\" href=\"https://uctb.github.io/UCTB/md_file/tutorial.html\"><strong>tutorial section</strong></a>.</p>\n<div class=\"section\" id=\"urban-datasts\">\n<h2>1.1. Urban Datasts<a class=\"headerlink\" href=\"#urban-datasts\" title=\"Permalink to this headline\">¶</a></h2>\n<p>UCTB also releases <a class=\"reference external\" href=\"https://github.com/uctb/Urban-Dataset\">a public dataset repository</a> including the following applications:</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\"><strong>Application</strong></th>\n<th align=\"center\"><strong>City</strong></th>\n<th align=\"center\"><strong>Time Range</strong></th>\n<th align=\"center\"><strong>Temporal Granularity</strong></th>\n<th align=\"center\"><strong>Dataset Link</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip\">66.0M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">Chicago</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip\">30.2M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">DC</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip\">31.0M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Pedestrian Count</td>\n<td align=\"center\">Melbourne</td>\n<td align=\"center\">2021.01.01-2022.11.01</td>\n<td align=\"center\">60 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip\">1.18M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Vehicle Speed</td>\n<td align=\"center\">LA</td>\n<td align=\"center\">2012.03.01-2012.06.28</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip\">11.8M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Vehicle Speed</td>\n<td align=\"center\">BAY</td>\n<td align=\"center\">2017.01.01-2017.07.01</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip\">27.9M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Taxi Demand</td>\n<td align=\"center\">Chicago</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip\">6.1M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bus</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2022.02.01-2024.01.13</td>\n<td align=\"center\">60 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip\">4.89M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Metro</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2022.02.01-2023.12.21</td>\n<td align=\"center\">60 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip\">11.3M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Traffic Flow</td>\n<td align=\"center\">Luzern</td>\n<td align=\"center\">2015.01.01-2016.01.01</td>\n<td align=\"center\">3 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Flow/3_minutes/Flow_Luzern.zip\">21M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">Chicago (community)</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip\">6.06</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">Chicago (census tract)</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip\">10M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2009.01.01-2023.06.01</td>\n<td align=\"center\">5 mins</td>\n<td align=\"center\"></td>\n</tr>\n</tbody>\n</table><p>We provide <a class=\"reference external\" href=\"https://github.com/uctb/Urban-Dataset/blob/main/Tutorial/tutorial.ipynb\">detailed documents</a> about how to build and how to use these datasets.</p>\n</div>\n<div class=\"section\" id=\"predictive-tool\">\n<h2>1.2. Predictive Tool<a class=\"headerlink\" href=\"#predictive-tool\" title=\"Permalink to this headline\">¶</a></h2>\n<p>Currently, the package supports the following models: (This toolbox is constructed based on some open-source repos. We appreciate these awesome implements. <a class=\"reference external\" href=\"https://uctb.github.io/UCTB/md_file/static/current_supported_models.html\">See more details</a>).</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th>Model Name</th>\n<th>Input Data Format</th>\n<th>Spatial Modeling Technique</th>\n<th>Graph Type</th>\n<th>Temporal Modeling Technique</th>\n<th>Temporal Knowledge</th>\n<th>Module</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>ARIMA</td>\n<td>Both</td>\n<td>N/A</td>\n<td>N/A</td>\n<td>SARIMA</td>\n<td>Closeness</td>\n<td><code>UCTB.model.ARIMA</code></td>\n</tr>\n<tr>\n<td>HM</td>\n<td>Both</td>\n<td>N/A</td>\n<td>N/A</td>\n<td>N/A</td>\n<td>Closeness</td>\n<td><code>UCTB.model.HM</code></td>\n</tr>\n<tr>\n<td>HMM</td>\n<td>Both</td>\n<td>N/A</td>\n<td>N/A</td>\n<td>HMM</td>\n<td>Closeness</td>\n<td><code>UCTB.model.HMM</code></td>\n</tr>\n<tr>\n<td>XGBoost</td>\n<td>Both</td>\n<td>N/A</td>\n<td>N/A</td>\n<td>XGBoost</td>\n<td>Closeness</td>\n<td><code>UCTB.model.XGBoost</code></td>\n</tr>\n<tr>\n<td>DeepST <a href=\"https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf\">[SIGSPATIAL 2016]</a></td>\n<td>Grid</td>\n<td>CNN</td>\n<td>N/A</td>\n<td>CNN</td>\n<td>Closeness,Period,Trend</td>\n<td><code>UCTB.model.DeepST</code></td>\n</tr>\n<tr>\n<td>ST-ResNet <a href=\"https://arxiv.org/pdf/1610.00081.pdf\">[AAAI 2017]</a></td>\n<td>Grid</td>\n<td>CNN</td>\n<td>N/A</td>\n<td>CNN</td>\n<td>Closeness,Period,Trend</td>\n<td><code>UCTB.model.ST_ResNet</code></td>\n</tr>\n<tr>\n<td>DCRNN  <a href=\"https://arxiv.org/pdf/1707.01926.pdf\">[ICLR 2018]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Prior</strong>(Sensor Network)</td>\n<td>RNN</td>\n<td>Closeness</td>\n<td><code>UCTB.model.DCRNN</code></td>\n</tr>\n<tr>\n<td>GeoMAN  <a href=\"https://www.ijcai.org/proceedings/2018/0476.pdf\">[IJCAI 2018]</a></td>\n<td>Node</td>\n<td>Attention</td>\n<td><strong>Prior</strong>(Sensor Networks)</td>\n<td>Attention+LSTM</td>\n<td>Closeness</td>\n<td><code>UCTB.model.GeoMAN</code></td>\n</tr>\n<tr>\n<td>STGCN  <a href=\"https://www.ijcai.org/proceedings/2018/0505.pdf\">[IJCAI 2018]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Prior</strong>(Traffic Network)</td>\n<td>Gated CNN</td>\n<td>Closeness</td>\n<td><code>UCTB.model.STGCN</code></td>\n</tr>\n<tr>\n<td>GraphWaveNet <a href=\"https://www.ijcai.org/proceedings/2019/0264.pdf\">[IJCAI 2019]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Adaptive</strong></td>\n<td>TCN</td>\n<td>Closeness</td>\n<td><code>UCTB.model.GraphWaveNet</code></td>\n</tr>\n<tr>\n<td>ASTGCN  <a href=\"https://ojs.aaai.org/index.php/AAAI/article/view/3881\">[AAAI 2019]</a></td>\n<td>Node</td>\n<td>GNN+Attention</td>\n<td><strong>Prior</strong>(Traffic Network)</td>\n<td>Attention</td>\n<td>Closeness,Period,Trend</td>\n<td><code>UCTB.model.ASTGCN</code></td>\n</tr>\n<tr>\n<td>ST-MGCN   <a href=\"https://ojs.aaai.org/index.php/AAAI/article/view/4247\">[AAAI 2019]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Prior</strong>(Neighborhood,Functional similarity,Transportation connectivity)</td>\n<td>CGRNN</td>\n<td>Closeness</td>\n<td><code>UCTB.model.ST_MGCN</code></td>\n</tr>\n<tr>\n<td>GMAN  <a href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5477/5333\">[AAAI 2020]</a></td>\n<td>Node</td>\n<td>Attention</td>\n<td><strong>Prior</strong>(Road Network)</td>\n<td>Attention</td>\n<td>Closeness</td>\n<td><code>UCTB.model.GMAN</code></td>\n</tr>\n<tr>\n<td>STSGCN  <a href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5438\">[AAAI 2020]</a></td>\n<td>Node</td>\n<td>GNN+Attention</td>\n<td><strong>Prior</strong>(Spatial Network)</td>\n<td>Attention</td>\n<td>Closeness</td>\n<td><code>UCTB.model.STSGCN</code></td>\n</tr>\n<tr>\n<td>AGCRN <a href=\"https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf\">[NeurIPS 2020]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Adaptive</strong></td>\n<td>RNN</td>\n<td>Closeness</td>\n<td><code>UCTB.model.AGCRN</code></td>\n</tr>\n<tr>\n<td>STMeta <a href=\"https://arxiv.org/abs/2009.09379\">[TKDE 2021]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Prior</strong>(Proximity,Functionality,Interaction/Same-line)</td>\n<td>LSTM/RNN</td>\n<td>Closeness,Period,Trend</td>\n<td><code>UCTB.model.STMeta</code></td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"visualization-tool\">\n<h2>1.3. Visualization Tool<a class=\"headerlink\" href=\"#visualization-tool\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The Visualization tool integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis.</p>\n<p>Welcome to visit the <a class=\"reference external\" href=\"http://39.107.116.221/\">website</a> for a trial!</p>\n<p><u><a class=\"reference external\" href=\"../index.html\">Back To HomePage</a></u></p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"installation.html\" class=\"btn btn-neutral float-right\" title=\"2. Installation\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"../index.html\" class=\"btn btn-neutral\" title=\"Welcome to UCTB’s documentation!\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/md_file/predictive_tool.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>4. Predictive Tool &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"5. Visualization-tool\" href=\"visualization_tool.html\"/>\n        <link rel=\"prev\" title=\"3. Urban Datasets\" href=\"urban_dataset.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">4. Predictive Tool</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#currently-supported-models\">4.1. Currently Supported Models</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#agcrn\">4.1.1. AGCRN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#arima\">4.1.2. ARIMA</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#astgcn\">4.1.3. ASTGCN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#dcrnn\">4.1.4. DCRNN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#deepst\">4.1.5. DeepST</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#geoman\">4.1.6. GeoMAN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#gman\">4.1.7. GMAN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#graphwavenet\">4.1.8. GraphWaveNet</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#hm-historical-mean\">4.1.9. HM (Historical Mean)</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#hmm-hidden-markov-model\">4.1.10. HMM (Hidden Markov Model)</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#stgcn\">4.1.11. STGCN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#stmeta\">4.1.12. STMeta</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#st-mgcn\">4.1.13. ST-MGCN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#st-resnet\">4.1.14. ST-ResNet</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#stsgcn\">4.1.15. STSGCN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#xgboost\">4.1.16. XGBoost</a></li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#quick-start\">4.2. Quick Start</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#quick-start-with-stmeta\">4.2.1. Quick start with STMeta</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#quick-start-with-hm\">4.2.2. Quick Start with HM</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#quick-start-with-arima\">4.2.3. Quick Start with ARIMA</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#quick-start-with-hmm\">4.2.4. Quick Start with HMM</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#quick-start-with-xgboost\">4.2.5. Quick Start with XGBoost</a></li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#tutorial\">4.3. Tutorial</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#load-datasets-from-urban-dataset\">4.3.1. Load datasets from Urban_dataset</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#model-definition-train-test-and-evaluation\">4.3.2. Model definition, train, test and evaluation</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#single-vs-multiple-kinds-of-temporal-knowledge\">4.3.3. Single vs. Multiple kinds of temporal knowledge</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"#use-temporal-closeness-feature-in-regression\">4.3.3.1. Use temporal closeness feature in regression</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"#make-full-use-of-closeness-period-and-trend-features\">4.3.3.2. Make full use of closeness, period, and trend features</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#advanced-features\">4.4. Advanced Features</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#build-your-own-model-using-uctb\">4.4.1. Build your own model using UCTB</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#build-your-own-graph-with-stmeta\">4.4.2. Build your own graph with STMeta</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>4. Predictive Tool</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/predictive_tool.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"predictive-tool\">\n<h1>4. Predictive Tool<a class=\"headerlink\" href=\"#predictive-tool\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"currently-supported-models\">\n<h2>4.1. Currently Supported Models<a class=\"headerlink\" href=\"#currently-supported-models\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"agcrn\">\n<h3>4.1.1. AGCRN<a class=\"headerlink\" href=\"#agcrn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>AGCRN (Adaptive Graph Convolutional Recurrent Network) is a deep nerual network for traffic prediction consisting of two adaptive module and recurrent networks.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf\">Bai, L., Yao, L., Li, C., Wang, X., &amp; Wang, C. (2020). Adaptive graph convolutional recurrent network for traffic forecasting.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/LeiBAI/AGCRN\">Github repository (LeiBAI)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"arima\">\n<h3>4.1.2. ARIMA<a class=\"headerlink\" href=\"#arima\" title=\"Permalink to this headline\">¶</a></h3>\n<p>ARIMA (Autoregressive Integrated Moving Average) is a widely used classical statistical model on time series prediction.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www3.nd.edu/%7Ebusiforc/handouts/ARIMA%20Engineering%20Article.pdf\">Williams, B. M., &amp; Hoel, L. A. (2003). Modeling and forecasting vehicular traffic flow as a seasonal ARIMA process: Theoretical basis and empirical results</a></li>\n</ul>\n</li>\n<li>Reference Package: <code class=\"docutils literal\"><span class=\"pre\">pandas</span></code>, <code class=\"docutils literal\"><span class=\"pre\">statsmodels</span></code></li>\n</ul>\n</div>\n<div class=\"section\" id=\"astgcn\">\n<h3>4.1.3. ASTGCN<a class=\"headerlink\" href=\"#astgcn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>ASTGCN (Attenion Based Spatial-temporal Graph Convolutional Networks) is a deep neural network for traffic flow forecasting. It models temporal-dependencies from three perspectives using attetion mechanism. And it models spatial-dependencies employing graph convolutions.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/3881\">Guo, S., Lin, Y., Feng, N., Song, C., &amp; Wan, H. (2019, July). Attention based spatial-temporal graph convolutional networks for traffic flow forecasting.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/guoshnBJTU/ASTGCN-r-pytorch\">Github repository (guoshnBJTU)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"dcrnn\">\n<h3>4.1.4. DCRNN<a class=\"headerlink\" href=\"#dcrnn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>DCRNN (Diffusion Convolutional Recurrent Neural Network) is a deep learning framework for traffic forecasting that incorporates both spatial and temporal dependency in the traffic flow. It captures the spatial dependency using bidirectional random walks on the graph, and the temporal dependency using the encoder-decoder architecture with scheduled sampling.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://arxiv.org/abs/1707.01926\">Li, Y., Yu, R., Shahabi, C., &amp; Liu, Y. (2017). Diffusion convolutional recurrent neural network: Data-driven traffic forecasting</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/liyaguang/DCRNN\">A TensorFlow implementation of Diffusion Convolutional Recurrent Neural Network (liyaguang)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"deepst\">\n<h3>4.1.5. DeepST<a class=\"headerlink\" href=\"#deepst\" title=\"Permalink to this headline\">¶</a></h3>\n<p>DeepST (Deep learning-based prediction model for Spatial-Temporal data) is composed of three components: 1) temporal dependent instances: describing temporal closeness, period and seasonal trend; 2) convolutional neural networks: capturing near and far spatial dependencies; 3) early and late fusions: fusing similar and different domains' data.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf\">Zhang, J., Zheng, Y., Qi, D., Li, R., &amp; Yi, X. (2016, October). DNN-based prediction model for spatio-temporal data</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"geoman\">\n<h3>4.1.6. GeoMAN<a class=\"headerlink\" href=\"#geoman\" title=\"Permalink to this headline\">¶</a></h3>\n<p>GeoMAN (Multi-level Attention Networks for Geo-sensory Time Series Prediction) consists of two major parts: 1) A multi-level attention mechanism (including both local and global  spatial attentions in encoder and temporal attention in decoder) to model the dynamic spatio-temporal  dependencies; 2) A general fusion module to incorporate the external factors from different domains (e.g.,  meteorology, time of day and land use).</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2018/0476.pdf\">Liang, Y., Ke, S., Zhang, J., Yi, X., &amp; Zheng, Y. (2018, July). GeoMAN: Multi-level Attention Networks for Geo-sensory Time Series Prediction</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/yoshall/GeoMAN\">An easy implement of GeoMAN using TensorFlow (yoshall &amp; CastleLiang)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"gman\">\n<h3>4.1.7. GMAN<a class=\"headerlink\" href=\"#gman\" title=\"Permalink to this headline\">¶</a></h3>\n<p>GMAN (Graph Multi-Attention Network) is a deep nerual network for traffic prediction adopting encoder-decoder architecture. Both encode and decoder consist of multiple spatio-temporal attention blocks to model spatio-temporal dependencies.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5477\">Zheng, C., Fan, X., Wang, C., &amp; Qi, J. (2020, April). Gman: A graph multi-attention network for traffic prediction.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/zhengchuanpan/GMAN\">implementation of Graph Multi-Attention Network</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"graphwavenet\">\n<h3>4.1.8. GraphWaveNet<a class=\"headerlink\" href=\"#graphwavenet\" title=\"Permalink to this headline\">¶</a></h3>\n<p>GraphWaveNet is an end-to-end novel graph neural network. It captures spatial dependencies through a self-adptive adjacency matrix. And it captures temporal dependencies through convolutions.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2019/0264.pdf\">Wu, Z., Pan, S., Long, G., Jiang, J., &amp; Zhang, C. (2019). Graph wavenet for deep spatial-temporal graph modeling.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/nnzhan/Graph-WaveNet\">Github repository (nnzhan)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"hm-historical-mean\">\n<h3>4.1.9. HM (Historical Mean)<a class=\"headerlink\" href=\"#hm-historical-mean\" title=\"Permalink to this headline\">¶</a></h3>\n<p>HM is a constant model and always forecasts the sample mean of the historical data.</p>\n</div>\n<div class=\"section\" id=\"hmm-hidden-markov-model\">\n<h3>4.1.10. HMM (Hidden Markov Model)<a class=\"headerlink\" href=\"#hmm-hidden-markov-model\" title=\"Permalink to this headline\">¶</a></h3>\n<p>Hidden Markov Model is a statistical Markov model in which the system being modeled is assumed to be a Markov process with hidden states. It is often used in temporal pattern recognition.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://ieeexplore.ieee.org/abstract/document/7785328\">Chen, Z., Wen, J., &amp; Geng, Y. (2016, November). Predicting future traffic using hidden markov models</a></li>\n</ul>\n</li>\n<li>Reference Package: <code class=\"docutils literal\"><span class=\"pre\">hmmlearn</span></code></li>\n</ul>\n</div>\n<div class=\"section\" id=\"stgcn\">\n<h3>4.1.11. STGCN<a class=\"headerlink\" href=\"#stgcn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>STGCN (Spatio-temporal Graph Convolutional Networks) is a deep learning framework for traffic forecasting with complete convolutional structures.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2018/0505.pdf\">Yu, B., Yin, H., &amp; Zhu, Z. (2017). Spatio-temporal graph convolutional networks: A deep learning framework for traffic forecasting.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/VeritasYin/STGCN_IJCAI-18\">Github repository (VeritasYin)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"stmeta\">\n<h3>4.1.12. STMeta<a class=\"headerlink\" href=\"#stmeta\" title=\"Permalink to this headline\">¶</a></h3>\n<p>STMeta is our prediction model, which requires extra graph information as input, and combines Graph Convolution LSTM and Attention mechanism.</p>\n<ul class=\"simple\">\n<li>Reference Package: <code class=\"docutils literal\"><span class=\"pre\">tensorflow</span></code></li>\n</ul>\n</div>\n<div class=\"section\" id=\"st-mgcn\">\n<h3>4.1.13. ST-MGCN<a class=\"headerlink\" href=\"#st-mgcn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>ST-MGCN (Spatiotemporal Multi-graph Convolution Network) is a deep learning based model which encoded the non-Euclidean correlations among regions using multiple graphs and explicitly captured them using multi-graph convolution.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://ieeexplore.ieee.org/abstract/document/7785328\">Geng, X., Li, Y., Wang, L., Zhang, L., Yang, Q., Ye, J., &amp; Liu, Y. (2019). Spatiotemporal multi-graph convolution network for ride-hailing demand forecasting</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/shawnwang-tech/ST-MGCN-pytorch\">A PyTorch implementation of the ST-MGCN model  (shawnwang-tech)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"st-resnet\">\n<h3>4.1.14. ST-ResNet<a class=\"headerlink\" href=\"#st-resnet\" title=\"Permalink to this headline\">¶</a></h3>\n<p>ST-ResNet is a deep-learning model with an end-to-end structure based on unique properties of spatio-temporal data making use of convolution and residual units.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://arxiv.org/pdf/1610.00081.pdf\">Zhang, J., Zheng, Y., &amp; Qi, D. (2017, February). Deep spatio-temporal residual networks for citywide crowd flows prediction</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/lucktroy/DeepST/tree/master/scripts/papers/AAAI17\">Github repository (lucktroy)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"stsgcn\">\n<h3>4.1.15. STSGCN<a class=\"headerlink\" href=\"#stsgcn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>STSGCN (Spatial-temporal Synchronous Graph Convolutional Networks) is a deep learning framework for spatial-temporal network data forecasting. It is able to capture spatial-temporal dependencies through a designed spatial-temporal synchronous modeling mechanism.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5438\">Song, C., Lin, Y., Guo, S., &amp; Wan, H. (2020, April). Spatial-temporal synchronous graph convolutional networks: A new framework for spatial-temporal network data forecasting.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/Davidham3/STSGCN\">Github repository (Davidham3)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"xgboost\">\n<h3>4.1.16. XGBoost<a class=\"headerlink\" href=\"#xgboost\" title=\"Permalink to this headline\">¶</a></h3>\n<p>XGBoost is a gradient boosting machine learning algorithm widely used in flow prediction and other machine learning prediction areas.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www.mdpi.com/2073-8994/10/9/386\">Alajali, W., Zhou, W., Wen, S., &amp; Wang, Y. (2018). Intersection Traffic Prediction Using Decision Tree Models</a></li>\n</ul>\n</li>\n<li>Reference Package: <code class=\"docutils literal\"><span class=\"pre\">xgboost</span></code></li>\n</ul>\n</div>\n</div>\n<div class=\"section\" id=\"quick-start\">\n<h2>4.2. Quick Start<a class=\"headerlink\" href=\"#quick-start\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"quick-start-with-stmeta\">\n<h3>4.2.1. Quick start with STMeta<a class=\"headerlink\" href=\"#quick-start-with-stmeta\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">STMeta</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.preprocess.GraphGenerator</span> <span class=\"kn\">import</span> <span class=\"n\">GraphGenerator</span>\n<span class=\"c1\"># Config data loader</span>\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span> <span class=\"n\">graph</span><span class=\"o\">=</span><span class=\"s1\">&#39;Correlation&#39;</span><span class=\"p\">,</span>\n                                <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Build Graph</span>\n<span class=\"n\">graph_obj</span> <span class=\"o\">=</span> <span class=\"n\">GraphGenerator</span><span class=\"p\">(</span><span class=\"n\">graph</span><span class=\"o\">=</span><span class=\"s1\">&#39;Correlation&#39;</span><span class=\"p\">,</span> <span class=\"n\">data_loader</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Init model object</span>\n<span class=\"n\">STMeta_Obj</span> <span class=\"o\">=</span> <span class=\"n\">STMeta</span><span class=\"p\">(</span><span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span><span class=\"p\">,</span>\n                    <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">period_len</span><span class=\"p\">,</span>\n                    <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">trend_len</span><span class=\"p\">,</span>\n                    <span class=\"n\">num_node</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">,</span>\n                    <span class=\"n\">num_graph</span><span class=\"o\">=</span><span class=\"n\">graph_obj</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span>\n                    <span class=\"n\">external_dim</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">external_dim</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Build tf-graph</span>\n<span class=\"n\">STMeta_Obj</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">()</span>\n<span class=\"c1\"># Training</span>\n<span class=\"n\">STMeta_Obj</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">closeness_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">,</span>\n               <span class=\"n\">period_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">,</span>\n               <span class=\"n\">trend_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">,</span>\n               <span class=\"n\">laplace_matrix</span><span class=\"o\">=</span><span class=\"n\">graph_obj</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"p\">,</span>\n               <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">,</span>\n               <span class=\"n\">external_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_ef</span><span class=\"p\">,</span>\n               <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_sequence_len</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Predict</span>\n<span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"n\">STMeta_Obj</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">closeness_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span>\n                                <span class=\"n\">period_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">,</span>\n                                <span class=\"n\">trend_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">,</span>\n                                <span class=\"n\">laplace_matrix</span><span class=\"o\">=</span><span class=\"n\">graph_obj</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"p\">,</span>\n                                <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">,</span>\n                                <span class=\"n\">external_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_ef</span><span class=\"p\">,</span>\n                                <span class=\"n\">output_names</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">],</span>\n                                <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_sequence_len</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Evaluate</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Test result&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_denormal</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]),</span>\n                                 <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_denormal</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">)))</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"quick-start-with-hm\">\n<h3>4.2.2. Quick Start with HM<a class=\"headerlink\" href=\"#quick-start-with-hm\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">HM</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span> <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n                                <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n<span class=\"n\">hm_obj</span> <span class=\"o\">=</span> <span class=\"n\">HM</span><span class=\"p\">(</span><span class=\"n\">c</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span><span class=\"p\">,</span> <span class=\"n\">p</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">period_len</span><span class=\"p\">,</span> <span class=\"n\">t</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">trend_len</span><span class=\"p\">)</span>\n\n<span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"n\">hm_obj</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">closeness_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span>\n                            <span class=\"n\">period_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">,</span>\n                            <span class=\"n\">trend_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">)</span>\n\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;RMSE&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">,</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">))</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"quick-start-with-arima\">\n<h3>4.2.3. Quick Start with ARIMA<a class=\"headerlink\" href=\"#quick-start-with-arima\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">ARIMA</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span> <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">24</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n                                <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n<span class=\"n\">test_prediction_collector</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n<span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"n\">model_obj</span> <span class=\"o\">=</span> <span class=\"n\">ARIMA</span><span class=\"p\">(</span><span class=\"n\">time_sequence</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                          <span class=\"n\">order</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">seasonal_order</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n        <span class=\"n\">test_prediction</span> <span class=\"o\">=</span> <span class=\"n\">model_obj</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">time_sequences</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                                            <span class=\"n\">forecast_step</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"k\">except</span> <span class=\"ne\">Exception</span> <span class=\"k\">as</span> <span class=\"n\">e</span><span class=\"p\">:</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Converge failed with error&#39;</span><span class=\"p\">,</span> <span class=\"n\">e</span><span class=\"p\">)</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Using last as prediction&#39;</span><span class=\"p\">)</span>\n        <span class=\"n\">test_prediction</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:,</span> <span class=\"p\">:]</span>\n    <span class=\"n\">test_prediction_collector</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">test_prediction</span><span class=\"p\">)</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Station&#39;</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"s1\">&#39;finished&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">test_rmse</span> <span class=\"o\">=</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">(</span><span class=\"n\">test_prediction_collector</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">)</span>\n\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;test_rmse&#39;</span><span class=\"p\">,</span> <span class=\"n\">test_rmse</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"quick-start-with-hmm\">\n<h3>4.2.4. Quick Start with HMM<a class=\"headerlink\" href=\"#quick-start-with-hmm\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">HMM</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span>\n                                <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n                                <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n<span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n<span class=\"k\">for</span> <span class=\"n\">station_index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">):</span>\n    <span class=\"c1\"># train the hmm model</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"n\">hmm</span> <span class=\"o\">=</span> <span class=\"n\">HMM</span><span class=\"p\">(</span><span class=\"n\">num_components</span><span class=\"o\">=</span><span class=\"mi\">8</span><span class=\"p\">,</span> <span class=\"n\">n_iter</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n        <span class=\"n\">hmm</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">station_index</span><span class=\"p\">:</span><span class=\"n\">station_index</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n        <span class=\"c1\"># predict</span>\n        <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"k\">for</span> <span class=\"n\">time_index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]):</span>\n            <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">hmm</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[</span><span class=\"n\">time_index</span><span class=\"p\">,</span> <span class=\"n\">station_index</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"p\">:],</span> <span class=\"n\">length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n    <span class=\"k\">except</span> <span class=\"ne\">Exception</span> <span class=\"k\">as</span> <span class=\"n\">e</span><span class=\"p\">:</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Failed at station&#39;</span><span class=\"p\">,</span> <span class=\"n\">station_index</span><span class=\"p\">,</span> <span class=\"s1\">&#39;with error&#39;</span><span class=\"p\">,</span> <span class=\"n\">e</span><span class=\"p\">)</span>\n        <span class=\"c1\"># using zero as prediction</span>\n        <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"p\">[[[</span><span class=\"mi\">0</span><span class=\"p\">]]</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])]</span>\n\n    <span class=\"n\">prediction</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">p</span><span class=\"p\">)[:,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">,</span> <span class=\"n\">station_index</span><span class=\"p\">,</span> <span class=\"s1\">&#39;finished&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">])</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;RMSE&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">,</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">))</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"quick-start-with-xgboost\">\n<h3>4.2.5. Quick Start with XGBoost<a class=\"headerlink\" href=\"#quick-start-with-xgboost\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">XGBoost</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span> <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span>\n                                <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n<span class=\"n\">prediction_test</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n<span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">):</span>\n\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;*************************************************************&#39;</span><span class=\"p\">)</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Station&#39;</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">)</span>\n\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">XGBoost</span><span class=\"p\">(</span><span class=\"n\">n_estimators</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"n\">max_depth</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">objective</span><span class=\"o\">=</span><span class=\"s1\">&#39;reg:squarederror&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span>\n              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n\n    <span class=\"n\">p_test</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                                           <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                                           <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n\n    <span class=\"n\">prediction_test</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">p_test</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]))</span>\n\n<span class=\"n\">prediction_test</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">(</span><span class=\"n\">prediction_test</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Test RMSE&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction_test</span><span class=\"p\">,</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">))</span>\n</pre></div>\n</div>\n</div>\n</div>\n<div class=\"section\" id=\"tutorial\">\n<h2>4.3. Tutorial<a class=\"headerlink\" href=\"#tutorial\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The general process of completing a spatiotemporal prediction task includes: loading dataset, defining model, training, testing, model evaluation.</p>\n<p><img alt=\"tutorial\" src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/tutorial.png\" /></p>\n<div class=\"section\" id=\"load-datasets-from-urban-dataset\">\n<h3>4.3.1. Load datasets from Urban_dataset<a class=\"headerlink\" href=\"#load-datasets-from-urban-dataset\" title=\"Permalink to this headline\">¶</a></h3>\n<p>To help better accuse dataset, UCTB provides data loader APIs <code class=\"docutils literal\"><span class=\"pre\">UCTB.dataset.data_loader</span></code>, which can be used to preprocess data, including <strong>data division</strong>, <strong>normalization</strong>, and <strong>extract temporal and spatial knowledge</strong>.</p>\n<p>In the following tutorial, we will illustrate how to use <code class=\"docutils literal\"><span class=\"pre\">UCTB.dataset.data_loader</span></code> APIs to inspect the speed dataset.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset.data_loader</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n</pre></div>\n</div>\n<p>We use all(data_range='all') of speed data in METR_LA(Assume that scripts are put under root directory, METR_LA dataset is put under <code class=\"docutils literal\"><span class=\"pre\">./data</span></code> directory.). Firstly, let's initialize a NodeTrafficLoader object:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;LA&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">data_range</span><span class=\"o\">=</span><span class=\"s1\">&#39;all&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">train_data_length</span><span class=\"o\">=</span><span class=\"s1\">&#39;all&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">test_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span>\n                 <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span>\n                 <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">,</span>\n                 <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span>\n                 <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span>\n                 <span class=\"n\">data_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;data&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">MergeIndex</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">MergeWay</span><span class=\"o\">=</span><span class=\"s2\">&quot;sum&quot;</span><span class=\"p\">,</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;METR&#39;</span><span class=\"p\">,</span><span class=\"n\">remove</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>NodeTrafficLoader is the base class for dataset extracting and processing. Input arguments appeared in constructor above will be explained.</p>\n<ul class=\"simple\">\n<li>data range selection\n<code class=\"docutils literal\"><span class=\"pre\">*data</span> <span class=\"pre\">range</span> <span class=\"pre\">=</span> <span class=\"pre\">'all'</span></code> means that we choose the whole data as our traffic_data to train, test, and predict.</li>\n<li>data spliting(train set and test set spliting)</li>\n</ul>\n<p><code class=\"docutils literal\"><span class=\"pre\">train_data</span> <span class=\"pre\">length</span> <span class=\"pre\">=</span> <span class=\"pre\">'all'</span></code> means that we exploit all of the traffic_data. <code class=\"docutils literal\"><span class=\"pre\">'train_test_ratio</span> <span class=\"pre\">=</span> <span class=\"pre\">0.1</span></code> means we divide the dataset into train and test sets. And the train set to the test set is nine to one.</p>\n<ul class=\"simple\">\n<li>normalization</li>\n</ul>\n<p><code class=\"docutils literal\"><span class=\"pre\">normalization</span> <span class=\"pre\">=</span> <span class=\"pre\">False</span></code> means that we normalized the dataset through min-max-normalization method. When we input False, we simply do not employ any preprocessing tricks on the dataset.</p>\n<ul class=\"simple\">\n<li>data merging</li>\n</ul>\n<p><code class=\"docutils literal\"><span class=\"pre\">MergeIndex</span> <span class=\"pre\">=</span> <span class=\"pre\">1,</span> <span class=\"pre\">MergeWay</span> <span class=\"pre\">=</span> <span class=\"pre\">'sum'</span></code> means that granularity of raw dataset will not be changed. If we try MergeIndex &gt; 1, we can obtain combination of MergeIndex time slots of data in a way of 'sum' or 'average'.</p>\n<ul class=\"simple\">\n<li>multiple time series building(temporal knowledge exploiting)</li>\n</ul>\n<p><code class=\"docutils literal\"><span class=\"pre\">closeness_len</span> <span class=\"pre\">=</span> <span class=\"pre\">6,</span> <span class=\"pre\">period_len=7,</span> <span class=\"pre\">trend_len=4,</span> <span class=\"pre\">target_length=1</span></code> means that we create 3 time series, using former consecutive closeness_len time slots of data as a unit, former every other daily_slots time slots of data as a unit(consisting of period_len piece of data), former every other daily_slots*7 time slots of data as a unit(consisting of trend_len piece of data) respectively.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">30844</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>You may probably note that the length of train_closeness is 13778 less than that of train_data. It's because we choose the shortest data length among the three series(train_trend) for alignment.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/data_reassemble.png\" style=\"zoom: 10%;\" /><p>Above is the visualization of a new time series's construction. In this situation, feature_stride = 3(means sampling interval), feature_step = 3(means how many times we sample).Other time series are just the same situation.</p>\n<p>Through the process in the figure shown above, we can calculate the length of train_trend is $30844-12<em>24</em>7*4=22780$, which is the minimum among three time series.</p>\n<p><strong>Operations</strong></p>\n<ul class=\"simple\">\n<li>Denormalization/Normalization</li>\n<li>Visualization</li>\n<li>Temporal Knowledge Exploitation</li>\n<li>Spatial knowledge Exploration</li>\n<li>Access to raw data</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">matplotlib.pyplot</span> <span class=\"k\">as</span> <span class=\"nn\">plt</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.preprocess.preprocessor</span> <span class=\"kn\">import</span> <span class=\"n\">Normalizer</span>\n\n<span class=\"c1\"># without normalization</span>\n\n<span class=\"n\">target_node</span> <span class=\"o\">=</span> <span class=\"mi\">5</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"p\">[:,</span><span class=\"mi\">5</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">title</span><span class=\"p\">(</span><span class=\"s1\">&#39;Raw&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n\n<span class=\"c1\"># normalization</span>\n\n<span class=\"n\">normalizer</span><span class=\"o\">=</span><span class=\"n\">Normalizer</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"p\">)</span>\n<span class=\"n\">X_normalized</span> <span class=\"o\">=</span> <span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_normal</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># denormalization</span>\n\n<span class=\"n\">X_denormalized</span> <span class=\"o\">=</span> <span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_denormal</span><span class=\"p\">(</span><span class=\"n\">X_normalized</span><span class=\"p\">)</span>\n\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">X_normalized</span><span class=\"p\">[:,</span><span class=\"mi\">5</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">title</span><span class=\"p\">(</span><span class=\"s1\">&#39;Normalized&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">X_denormalized</span><span class=\"p\">[:,</span><span class=\"mi\">5</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">title</span><span class=\"p\">(</span><span class=\"s1\">&#39;Denormalized&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n</pre></div>\n</div>\n<p><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Raw_data.png\" alt=\"Raw_data\" style=\"zoom:33%;\" /><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/normalized_data.png\" style=\"zoom:33%;\" /><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/denormalized_data.png\" style=\"zoom:33%;\" /></p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># Nodes&#39; location visualizations</span>\n<span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">st_map</span><span class=\"p\">()</span>\n</pre></div>\n</div>\n<p>Visualization result is as follows:</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/METR_LA.png\" alt=\"Node location of METR_LA\" style=\"zoom: 50%;\" /><div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># data visualization</span>\n<span class=\"kn\">import</span> <span class=\"nn\">seaborn</span> <span class=\"k\">as</span> <span class=\"nn\">sns</span>\n<span class=\"kn\">import</span> <span class=\"nn\">matplotlib.pyplot</span> <span class=\"k\">as</span> <span class=\"nn\">plt</span>\n<span class=\"n\">real_denormed</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_denormal</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">)</span>\n<span class=\"n\">sns</span><span class=\"o\">.</span><span class=\"n\">heatmap</span><span class=\"p\">(</span><span class=\"n\">real_denormed</span><span class=\"p\">[:,:,</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">cmap</span><span class=\"o\">=</span><span class=\"s1\">&#39;Reds&#39;</span><span class=\"p\">,</span> <span class=\"n\">vmin</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1000</span><span class=\"p\">,</span> <span class=\"n\">vmax</span> <span class=\"o\">=</span> <span class=\"mi\">4000</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">ylabel</span><span class=\"p\">(</span><span class=\"s2\">&quot;Time Slot&quot;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">xlabel</span><span class=\"p\">(</span><span class=\"s2\">&quot;Sensor Node&quot;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">title</span><span class=\"p\">(</span><span class=\"s2\">&quot;Visualization&quot;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># Feature stitching</span>\n<span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">make_concat</span><span class=\"p\">()</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;before concatenate&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;closeness&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;period&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;trend&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;After concatenate&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"n\">before</span> <span class=\"n\">concatenate</span>\n<span class=\"n\">closeness</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">period</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">trend</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">After</span> <span class=\"n\">concatenate</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">17</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># access to raw data</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">])</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"mf\">64.375</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"model-definition-train-test-and-evaluation\">\n<h3>4.3.2. Model definition, train, test and evaluation<a class=\"headerlink\" href=\"#model-definition-train-test-and-evaluation\" title=\"Permalink to this headline\">¶</a></h3>\n<p>We use XGBoost interface in UCTB as an example to define a model. Since there are total 207 stations in METR_LA dataset, we define 207 XGBoost models respectively. They are trained and tested in their own iteration related to stations. Finally, when we evaluate our model, we consider the prediction results as a whole and evaluate it against GroundTruth provided by <code class=\"docutils literal\"><span class=\"pre\">data_loader</span></code> using <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Root-mean-square_deviation\">RMSE</a> metric.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">XGBoost</span>\n<span class=\"kn\">import</span> <span class=\"nn\">UCTB.evaluation.metric</span> <span class=\"k\">as</span> <span class=\"nn\">metric</span>\n<span class=\"n\">prediction_test</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n<span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">):</span>\n\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;*************************************************************&#39;</span><span class=\"p\">)</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Station&#39;</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">)</span>\n\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">XGBoost</span><span class=\"p\">(</span><span class=\"n\">n_estimators</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"n\">max_depth</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">objective</span><span class=\"o\">=</span><span class=\"s1\">&#39;reg:squarederror&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span>\n              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n\n    <span class=\"n\">p_test</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                                           <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                                           <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n\n    <span class=\"n\">prediction_test</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">p_test</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]))</span>\n\n<span class=\"n\">prediction_test</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">(</span><span class=\"n\">prediction_test</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n\n<span class=\"n\">y_truth</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">inverse_transform</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">)</span>\n<span class=\"n\">y_pred</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">inverse_transform</span><span class=\"p\">(</span><span class=\"n\">prediction_test</span><span class=\"p\">)</span>\n<span class=\"n\">y_truth</span> <span class=\"o\">=</span> <span class=\"n\">y_truth</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">207</span><span class=\"p\">])</span>\n<span class=\"n\">y_pred</span> <span class=\"o\">=</span> <span class=\"n\">y_pred</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">207</span><span class=\"p\">])</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Test RMSE&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">y_pred</span><span class=\"p\">,</span> <span class=\"n\">y_truth</span><span class=\"p\">))</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">title</span><span class=\"p\">(</span><span class=\"s1\">&#39;XGBoost Result&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">xlabel</span><span class=\"p\">(</span><span class=\"s1\">&#39;Time Slot&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">ylabel</span><span class=\"p\">(</span><span class=\"s1\">&#39;Speed&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">y_pred</span><span class=\"p\">[:</span><span class=\"mi\">12</span><span class=\"o\">*</span><span class=\"mi\">24</span><span class=\"o\">*</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"n\">target_node</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">y_truth</span><span class=\"p\">[:</span><span class=\"mi\">12</span><span class=\"o\">*</span><span class=\"mi\">24</span><span class=\"o\">*</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"n\">target_node</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">legend</span><span class=\"p\">([</span><span class=\"s1\">&#39;gt&#39;</span><span class=\"p\">,</span><span class=\"s1\">&#39;pred&#39;</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n</pre></div>\n</div>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/XGBoost_Result.png\" alt=\"XGBoost Result\" style=\"zoom:50%;\" /><div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"n\">Test</span> <span class=\"n\">RMSE</span> <span class=\"mf\">5.549781682961724</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"single-vs-multiple-kinds-of-temporal-knowledge\">\n<h3>4.3.3. Single vs. Multiple kinds of temporal knowledge<a class=\"headerlink\" href=\"#single-vs-multiple-kinds-of-temporal-knowledge\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"section\" id=\"use-temporal-closeness-feature-in-regression\">\n<h4>4.3.3.1. Use temporal closeness feature in regression<a class=\"headerlink\" href=\"#use-temporal-closeness-feature-in-regression\" title=\"Permalink to this headline\">¶</a></h4>\n<p>UCTB provides many classical and popular spatial-temporal predicting models. These models can be used to either predicting series for a single station or all stations. You can find the details in <a class=\"reference external\" href=\"./static/current_supported_models.html\"><code class=\"docutils literal\"><span class=\"pre\">UCTB.model</span></code></a>.</p>\n<p>The following example shows how to use a <strong>XGBoost</strong> model to handle a simple time series predicting a problem. We will try to predict the bike demands <code class=\"docutils literal\"><span class=\"pre\">test_y</span></code> of a fixed station <code class=\"docutils literal\"><span class=\"pre\">target_node</span></code> in New York City by checking back the historical demands in recent time slots <code class=\"docutils literal\"><span class=\"pre\">train_closeness</span></code>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">matplotlib.pyplot</span> <span class=\"k\">as</span> <span class=\"nn\">plt</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">XGBoost</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n<span class=\"n\">target_node</span> <span class=\"o\">=</span> <span class=\"mi\">233</span>\n</pre></div>\n</div>\n<p>When initializing the loader, we use past <code class=\"docutils literal\"><span class=\"pre\">12</span></code> time slots (timesteps) of closeness as input, <code class=\"docutils literal\"><span class=\"pre\">1</span></code> timestep in the next as output and set the timesteps of other features <code class=\"docutils literal\"><span class=\"pre\">period_len</span></code>, <code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> to zero.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span> <span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span>\n                                <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n                                <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">test_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.2</span><span class=\"p\">,</span> \n                                <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">with_tpe</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>The well-loaded data contain all <code class=\"docutils literal\"><span class=\"pre\">717</span></code> stations' data. Therefore it is needed to specify the target station by <code class=\"docutils literal\"><span class=\"pre\">target_station</span></code>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"p\">(</span><span class=\"mi\">2967</span><span class=\"p\">,</span> <span class=\"mi\">717</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,</span> <span class=\"mi\">717</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,</span> <span class=\"mi\">717</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">train_x</span><span class=\"p\">,</span> <span class=\"n\">test_x</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">train_y</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">test_y</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n</pre></div>\n</div>\n<p>Inspect the shape of data. Here are the all we need for one-station prediction.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">train_x</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">train_y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">test_x</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">test_y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"p\">(</span><span class=\"mi\">2967</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">2967</span><span class=\"p\">,)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,)</span>\n</pre></div>\n</div>\n<p>Build the XGBoost model.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">XGBoost</span><span class=\"p\">(</span><span class=\"n\">n_estimators</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"n\">max_depth</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">objective</span><span class=\"o\">=</span><span class=\"s1\">&#39;reg:linear&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Now, we can fit the model with the train dataset and make predictions on the test dataset.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"o\">=</span><span class=\"n\">train_x</span><span class=\"p\">)</span>\n<span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">test_x</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>We can evaluate the performance of the model by build-in <code class=\"docutils literal\"><span class=\"pre\">UCTB.evaluation</span></code> APIs.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">test_rmse</span> <span class=\"o\">=</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">predictions</span><span class=\"p\">,</span> <span class=\"n\">test_y</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">test_rmse</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"mf\">3.6033132</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"make-full-use-of-closeness-period-and-trend-features\">\n<h4>4.3.3.2. Make full use of closeness, period, and trend features<a class=\"headerlink\" href=\"#make-full-use-of-closeness-period-and-trend-features\" title=\"Permalink to this headline\">¶</a></h4>\n<p>In this case, let's take more temporal knowledge related to <code class=\"docutils literal\"><span class=\"pre\">target_node</span></code> into account. We will concatenate factors including <code class=\"docutils literal\"><span class=\"pre\">closeness</span></code>, <code class=\"docutils literal\"><span class=\"pre\">period</span></code>, and <code class=\"docutils literal\"><span class=\"pre\">trend</span></code>, and use <strong>XGBoost</strong> as the predicting model.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">matplotlib.pyplot</span> <span class=\"k\">as</span> <span class=\"nn\">plt</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">XGBoost</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n<span class=\"n\">target_node</span> <span class=\"o\">=</span> <span class=\"mi\">233</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span> <span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span>\n                                <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span>\n                                <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">test_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.2</span><span class=\"p\">,</span> \n                                <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">with_tpe</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n<span class=\"n\">train_closeness</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">train_period</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">[:,</span> <span class=\"n\">target_nodze</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">train_trend</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">train_y</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n\n<span class=\"n\">test_closeness</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">test_period</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">test_trend</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">test_y</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n\n<span class=\"n\">train_X</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">([</span><span class=\"n\">train_closeness</span><span class=\"p\">,</span> <span class=\"n\">train_period</span><span class=\"p\">,</span> <span class=\"n\">train_trend</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">test_X</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">([</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span> <span class=\"n\">test_period</span><span class=\"p\">,</span> <span class=\"n\">test_trend</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">train_X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">train_y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">test_X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">test_y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n\n<span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">XGBoost</span><span class=\"p\">(</span><span class=\"n\">n_estimators</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"n\">max_depth</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">objective</span><span class=\"o\">=</span><span class=\"s1\">&#39;reg:linear&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">train_X</span><span class=\"p\">,</span> <span class=\"n\">train_y</span><span class=\"p\">)</span>\n<span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">test_X</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Test RMSE&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">predictions</span><span class=\"p\">,</span> <span class=\"n\">test_y</span><span class=\"p\">))</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"p\">(</span><span class=\"mi\">2307</span><span class=\"p\">,</span> <span class=\"mi\">17</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">2307</span><span class=\"p\">,)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,</span> <span class=\"mi\">17</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,)</span>\n<span class=\"n\">Test</span> <span class=\"n\">RMSE</span> <span class=\"mf\">3.3267457</span>\n</pre></div>\n</div>\n</div>\n</div>\n</div>\n<div class=\"section\" id=\"advanced-features\">\n<h2>4.4. Advanced Features<a class=\"headerlink\" href=\"#advanced-features\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"build-your-own-model-using-uctb\">\n<h3>4.4.1. Build your own model using UCTB<a class=\"headerlink\" href=\"#build-your-own-model-using-uctb\" title=\"Permalink to this headline\">¶</a></h3>\n<p>UCTB provides extendable APIs to build your own model. Currently, it can support the running of all the <code class=\"docutils literal\"><span class=\"pre\">1.x</span></code> version of <strong>Tensorflow-based</strong> models. In the following tutorial, we will show you how to takes the least efforts to implement a UCTB model.</p>\n<p>Commonly, a new model needs to inherit <code class=\"docutils literal\"><span class=\"pre\">BaseModel</span></code> to acquire the features provided by UCTB, such as batch division, early stopping, etc. The necessary components for a subclass of <code class=\"docutils literal\"><span class=\"pre\">BaseModel</span></code> include:</p>\n<ul class=\"simple\">\n<li><code class=\"docutils literal\"><span class=\"pre\">self.__init__()</span></code>. Define the model's parameters related to the architecture. You should call the super class's constructor at first.</li>\n<li><code class=\"docutils literal\"><span class=\"pre\">self.build()</span></code>. Build the architecture here. You should construct the graph at the beginning of this function and call the super class's <code class=\"docutils literal\"><span class=\"pre\">build()</span></code> function at the end.</li>\n<li><code class=\"docutils literal\"><span class=\"pre\">self._input</span></code>. The <code class=\"docutils literal\"><span class=\"pre\">dict</span></code> used to record the acceptable inputs of the model, whose keys are the parameter names in <code class=\"docutils literal\"><span class=\"pre\">model.fit()</span></code> and <code class=\"docutils literal\"><span class=\"pre\">model.predict()</span></code> and values are the name of related tensors.</li>\n<li><code class=\"docutils literal\"><span class=\"pre\">self._output</span></code>. The <code class=\"docutils literal\"><span class=\"pre\">dict</span></code> used to record the outputs of the model. You should fill the required keys <code class=\"docutils literal\"><span class=\"pre\">prediction</span></code> and <code class=\"docutils literal\"><span class=\"pre\">loss</span></code> with the names of tensors in your case.</li>\n<li><code class=\"docutils literal\"><span class=\"pre\">self._op</span></code>. The <code class=\"docutils literal\"><span class=\"pre\">dict</span></code> used to define all the operations for the model. Basic usage for it is to record the <strong>training operation</strong>, for example, the minimizing loss operation of an optimizer. Use key <code class=\"docutils literal\"><span class=\"pre\">train_op</span></code> to record it.</li>\n</ul>\n<p>For more examples, you can refer to the implementations of build-in models in <a class=\"reference external\" href=\"../UCTB.model.html#uctb-model-package\"><code class=\"docutils literal\"><span class=\"pre\">UCTB.model</span></code></a>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">UCTB.model_unit</span> <span class=\"kn\">import</span> <span class=\"n\">BaseModel</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">MyModel</span><span class=\"p\">(</span><span class=\"n\">BaseModel</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 \n                 <span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;my_model&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span>\n                <span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">MyModel</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"n\">code_version</span><span class=\"p\">,</span> \n                                      <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"n\">model_dir</span><span class=\"p\">,</span> <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"n\">gpu_device</span><span class=\"p\">)</span>\n        <span class=\"o\">...</span>\n        \n    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n            <span class=\"o\">...</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;inputs&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;targets&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">targets</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            \n            <span class=\"o\">...</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">predictions</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">loss</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">train_op</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            \n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">MyModel</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">(</span><span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"n\">init_vars</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span> \n</pre></div>\n</div>\n<p>Next, in a concrete case, we will realize a <strong>Long short-term memory (LSTM)</strong> model to make the all-station prediction that accepts time series of <code class=\"docutils literal\"><span class=\"pre\">717</span></code> stations and predict the future of them as a whole.</p>\n<p>For the mechanism of LSTM, you can refer to\n<a class=\"reference external\" href=\"https://www.researchgate.net/profile/Felix_Gers/publication/12292425_Learning_to_Forget_Continual_Prediction_with_LSTM/links/5759414608ae9a9c954e84c5/Learning-to-Forget-Continual-Prediction-with-LSTM.pdf\">Gers, F. A., Schmidhuber, J., &amp; Cummins, F. (1999). Learning to forget: Continual prediction with LSTM</a>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model_unit</span> <span class=\"kn\">import</span> <span class=\"n\">BaseModel</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.preprocess</span> <span class=\"kn\">import</span> <span class=\"n\">SplitData</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"k\">class</span> <span class=\"nc\">LSTM</span><span class=\"p\">(</span><span class=\"n\">BaseModel</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 <span class=\"n\">num_stations</span><span class=\"p\">,</span> \n                 <span class=\"n\">num_layers</span><span class=\"p\">,</span> \n                 <span class=\"n\">num_units</span><span class=\"p\">,</span> \n                 <span class=\"n\">input_steps</span><span class=\"p\">,</span> \n                 <span class=\"n\">input_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">output_steps</span><span class=\"p\">,</span>\n                 <span class=\"n\">output_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;my_lstm&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">LSTM</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"n\">code_version</span><span class=\"p\">,</span> \n                                   <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"n\">model_dir</span><span class=\"p\">,</span> <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"n\">gpu_device</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span> <span class=\"o\">=</span> <span class=\"n\">num_stations</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_layers</span> <span class=\"o\">=</span> <span class=\"n\">num_layers</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_units</span> <span class=\"o\">=</span> <span class=\"n\">num_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_steps</span> <span class=\"o\">=</span> <span class=\"n\">input_steps</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_dim</span> <span class=\"o\">=</span> <span class=\"n\">input_dim</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_steps</span> <span class=\"o\">=</span> <span class=\"n\">output_steps</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_dim</span> <span class=\"o\">=</span> <span class=\"n\">output_dim</span>\n        \n    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n            <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span><span class=\"p\">,</span> \n                                                       <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_steps</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_dim</span><span class=\"p\">))</span>\n            <span class=\"n\">targets</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span><span class=\"p\">,</span>\n                                                       <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_steps</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_dim</span><span class=\"p\">))</span>\n            <span class=\"c1\"># record the inputs of the model</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;inputs&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;targets&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">targets</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_steps</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_dim</span><span class=\"p\">))</span>\n            \n            <span class=\"k\">def</span> <span class=\"nf\">get_a_cell</span><span class=\"p\">(</span><span class=\"n\">num_units</span><span class=\"p\">):</span>\n                <span class=\"n\">lstm</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">rnn_cell</span><span class=\"o\">.</span><span class=\"n\">BasicLSTMCell</span><span class=\"p\">(</span><span class=\"n\">num_units</span><span class=\"p\">,</span> <span class=\"n\">state_is_tuple</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n                <span class=\"k\">return</span> <span class=\"n\">lstm</span>\n            \n            <span class=\"n\">stacked_cells</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">rnn</span><span class=\"o\">.</span><span class=\"n\">MultiRNNCell</span><span class=\"p\">([</span><span class=\"n\">get_a_cell</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_units</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_layers</span><span class=\"p\">)],</span> <span class=\"n\">state_is_tuple</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n            <span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">final_state</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">dynamic_rnn</span><span class=\"p\">(</span><span class=\"n\">stacked_cells</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n            \n            <span class=\"n\">stacked_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_units</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_steps</span><span class=\"p\">))</span>\n            <span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">dense</span><span class=\"p\">(</span><span class=\"n\">stacked_outputs</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_steps</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_dim</span><span class=\"p\">)</span>\n            <span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">predictions</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_steps</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_dim</span><span class=\"p\">))</span>\n            \n            <span class=\"n\">loss</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">predictions</span> <span class=\"o\">-</span> <span class=\"n\">targets</span><span class=\"p\">)))</span>\n            <span class=\"n\">train_op</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">AdamOptimizer</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">minimize</span><span class=\"p\">(</span><span class=\"n\">loss</span><span class=\"p\">)</span>\n            \n            <span class=\"c1\"># record the outputs and the operation of the model</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">predictions</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">loss</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">train_op</span><span class=\"o\">.</span><span class=\"n\">name</span>\n        \n        <span class=\"c1\"># must call super class&#39; function to build </span>\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">LSTM</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">(</span><span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"n\">init_vars</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span> \n</pre></div>\n</div>\n<p>Load the dataset by loader and transform them into the formats your model accepts. If the loader APIs are not filled your demands, you can inherit loader and wrapper it according to your desires (see <a class=\"reference external\" href=\"./quickstart.html\">Quickstart</a> for more details).</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span> <span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span>\n                                <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n                                <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">test_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.2</span><span class=\"p\">,</span> \n                                <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">with_tpe</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n<span class=\"n\">train_y</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">expand_dims</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">test_y</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">expand_dims</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">LSTM</span><span class=\"p\">(</span><span class=\"n\">num_stations</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">,</span> \n             <span class=\"n\">num_layers</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n             <span class=\"n\">num_units</span><span class=\"o\">=</span><span class=\"mi\">512</span><span class=\"p\">,</span> \n             <span class=\"n\">input_steps</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> \n             <span class=\"n\">input_dim</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> \n             <span class=\"n\">output_steps</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> \n             <span class=\"n\">output_dim</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">()</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">trainable_vars</span><span class=\"p\">)</span>  <span class=\"c1\"># count the trainble parameters</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"mi\">6821581</span>\n</pre></div>\n</div>\n<p>Use your model to training and predicting. <code class=\"docutils literal\"><span class=\"pre\">model.fit()</span></code> method presets lots of useful functions, such as batch division and early stopping. Check them in <a class=\"reference external\" href=\"../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.fit\"><code class=\"docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel.fit</span></code></a>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">,</span>\n          <span class=\"n\">targets</span><span class=\"o\">=</span><span class=\"n\">train_y</span><span class=\"p\">,</span>\n          <span class=\"n\">max_epoch</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span>\n          <span class=\"n\">batch_size</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span>\n          <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_sequence_len</span><span class=\"p\">,</span>\n          <span class=\"n\">validate_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"n\">No</span> <span class=\"n\">model</span> <span class=\"n\">found</span><span class=\"p\">,</span> <span class=\"n\">start</span> <span class=\"n\">training</span>\n<span class=\"n\">Running</span> <span class=\"n\">Operation</span> <span class=\"p\">(</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">,)</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.016053785</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.01606118</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.015499311</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015820855</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">2</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.015298592</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015657894</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">3</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.015163456</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015559187</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">4</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.015066812</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015342651</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">5</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.015016247</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015287879</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">6</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.014899823</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015249459</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">7</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.014773054</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015098239</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">8</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.014655286</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015097916</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">9</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.014558283</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015108417</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span> \n                            <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_sequence_len</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Reverse the normalization by <code class=\"docutils literal\"><span class=\"pre\">data_loader</span></code> and evaluate the results:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">inverse_transform</span><span class=\"p\">(</span><span class=\"n\">predictions</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">])</span>\n<span class=\"n\">targets</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">inverse_transform</span><span class=\"p\">(</span><span class=\"n\">test_y</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Test result&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"o\">=</span><span class=\"n\">predictions</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"n\">targets</span><span class=\"p\">))</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"n\">Test</span> <span class=\"n\">result</span> <span class=\"mf\">2.9765626570592545</span>\n</pre></div>\n</div>\n<p>Since we only use a short period of the dataset (<code class=\"docutils literal\"><span class=\"pre\">data_range=0.1</span></code>) in this toy example, the result looks good compared with the <a class=\"reference external\" href=\"./all_results.html#results-on-bike\">experiment</a>. You can also take a try to test the completed dataset on your model.</p>\n</div>\n<div class=\"section\" id=\"build-your-own-graph-with-stmeta\">\n<h3>4.4.2. Build your own graph with STMeta<a class=\"headerlink\" href=\"#build-your-own-graph-with-stmeta\" title=\"Permalink to this headline\">¶</a></h3>\n<p>Next, we will use the Top-K graph as an example to illustrate how to build customized graphs in UCTB. All of the code in this section can be found <a class=\"reference external\" href=\"https://anonymous.4open.science/r/561305b5-e65e-46c6-9371-ae76b85109ee/Experiments/CustomizedDemo/\">here</a>.</p>\n<p><strong>Top-K graph</strong></p>\n<p>First of all, the customized graphs used in this section is called Top-K graph. We construct the corresponding adjacent graph by marking the point pair that consist of each point and its nearest K points as 1, and the others are marked as 0. Then, we use the adjacent graph to generate the laplacian matrix for input. The hyperparameter K is designed via ad-hoc heuristics. In this demonstration, we chose 23 as the value of K.</p>\n<p><strong>Realize TopK graph analysis module</strong></p>\n<p>To adopt customized graphs (<em><strong>e.g.,</strong></em> Top-K) in UCTB, you should first build your own analysis class by inheriting <code class=\"docutils literal\"><span class=\"pre\">UCTB.preprocess.GraphGenerator</span> <span class=\"pre\">class</span></code>.</p>\n<p>It is worth noting that the ultimate goal is to generate the member variables: <code class=\"docutils literal\"><span class=\"pre\">self.LM</span></code> and <code class=\"docutils literal\"><span class=\"pre\">self.AM</span></code>, which is the input matrix of the graph. In this phase, we need to make the corresponding analytical implementation according to the type of the custom graph passed in.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># &quot;UCTB/preprocess/topKGraph.py&quot;</span>\n<span class=\"kn\">import</span> <span class=\"nn\">heapq</span>\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.preprocess.GraphGenerator</span> <span class=\"kn\">import</span> <span class=\"n\">GraphGenerator</span>\n\n<span class=\"c1\"># Define the class: topKGraph</span>\n<span class=\"k\">class</span> <span class=\"nc\">topKGraph</span><span class=\"p\">(</span><span class=\"n\">GraphGenerator</span><span class=\"p\">):</span>  <span class=\"c1\"># Init NodeTrafficLoader</span>\n\n   <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n\n       <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">topKGraph</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n       \n       <span class=\"k\">for</span> <span class=\"n\">graph_name</span> <span class=\"ow\">in</span> <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;graph&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"s1\">&#39;-&#39;</span><span class=\"p\">):</span>\n\n<span class=\"c1\"># As the basic graph is implemented in GraphGenerator, you only need to implement your own graph function instead of the existing one.</span>\n           <span class=\"k\">if</span> <span class=\"n\">graph_name</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;topk&#39;</span><span class=\"p\">:</span>\n               <span class=\"n\">lat_lng_list</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([[</span><span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"n\">e1</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">e1</span> <span class=\"ow\">in</span> <span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">:</span><span class=\"mi\">4</span><span class=\"p\">]]</span>\n                                        <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_station_info</span><span class=\"p\">])</span>\n               <span class=\"c1\"># Handling</span>\n               <span class=\"n\">AM</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">neighbour_adjacent</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">],</span>\n                                       <span class=\"n\">threshold</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;threshold_neighbour&#39;</span><span class=\"p\">]))</span>\n               <span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">adjacent_to_laplacian</span><span class=\"p\">(</span><span class=\"n\">AM</span><span class=\"p\">)</span>\n\n               <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">AM</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>  <span class=\"c1\"># Make AM</span>\n                   <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">AM</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">AM</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n               <span class=\"k\">else</span><span class=\"p\">:</span>\n                   <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">AM</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">vstack</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">AM</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">AM</span><span class=\"p\">[</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">newaxis</span><span class=\"p\">,</span> <span class=\"p\">:])))</span>\n\n               <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>  <span class=\"c1\"># Make LM</span>\n                   <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">LM</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n               <span class=\"k\">else</span><span class=\"p\">:</span>\n                   <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">vstack</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">LM</span><span class=\"p\">[</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">newaxis</span><span class=\"p\">,</span> <span class=\"p\">:])))</span>\n\n<span class=\"c1\"># Implement the details of building the Top-K graph.</span>\n   <span class=\"k\">def</span> <span class=\"nf\">neighbour_adjacent</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">lat_lng_list</span><span class=\"p\">,</span> <span class=\"n\">threshold</span><span class=\"p\">):</span>\n       <span class=\"n\">adjacent_matrix</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">)])</span>\n       <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">)):</span>\n           <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">)):</span>\n               <span class=\"n\">adjacent_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">haversine</span><span class=\"p\">(</span>\n                   <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n       <span class=\"n\">dis_matrix</span> <span class=\"o\">=</span> <span class=\"n\">adjacent_matrix</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n       <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">dis_matrix</span><span class=\"p\">)):</span>\n           <span class=\"n\">ind</span> <span class=\"o\">=</span> <span class=\"n\">heapq</span><span class=\"o\">.</span><span class=\"n\">nlargest</span><span class=\"p\">(</span><span class=\"n\">threshold</span><span class=\"p\">,</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">dis_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])),</span> <span class=\"n\">dis_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">take</span><span class=\"p\">)</span>\n           <span class=\"n\">dis_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mi\">0</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">dis_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]))])</span>\n           <span class=\"n\">dis_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">ind</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">1</span>\n       <span class=\"n\">adjacent_matrix</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">adjacent_matrix</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n       <span class=\"k\">return</span> <span class=\"n\">adjacent_matrix</span>\n</pre></div>\n</div>\n<p><strong>Redefine the call statement of the above class</strong></p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># &quot;UCTB/Experiments/CustomizedDemo/STMeta_Obj_topk.py&quot;</span>\n\n<span class=\"c1\"># Import the Class: topKGraph</span>\n<span class=\"kn\">from</span> <span class=\"nn\">topKGraph</span> <span class=\"kn\">import</span> <span class=\"n\">topKGraph</span>\n<span class=\"c1\"># Call topKGraph to initialize and generate AM and LM</span>\n<span class=\"n\">graphBuilder</span> <span class=\"o\">=</span> <span class=\"n\">topKGraph</span><span class=\"p\">(</span><span class=\"n\">graph</span><span class=\"o\">=</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"s1\">&#39;graph&#39;</span><span class=\"p\">],</span>\n                         <span class=\"n\">data_loader</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"p\">,</span>\n                         <span class=\"n\">threshold_distance</span><span class=\"o\">=</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"s1\">&#39;threshold_distance&#39;</span><span class=\"p\">],</span>\n                         <span class=\"n\">threshold_correlation</span><span class=\"o\">=</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"s1\">&#39;threshold_correlation&#39;</span><span class=\"p\">],</span>\n                         <span class=\"n\">threshold_interaction</span><span class=\"o\">=</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"s1\">&#39;threshold_interaction&#39;</span><span class=\"p\">],</span>\n                         <span class=\"n\">threshold_neighbour</span><span class=\"o\">=</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"s1\">&#39;threshold_neighbour&#39;</span><span class=\"p\">])</span>\n<span class=\"c1\"># ......</span>\n</pre></div>\n</div>\n<p><strong>Modify the function call location</strong></p>\n<p>Add the new graph name when fitting model and then execute it for experiments. <a class=\"reference external\" href=\"https://github.com/uctb/UCTB/blob/master/Experiments/CustomizedDemo/Runner_topk.py\">code</a></p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj_topk.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line-TopK,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>We conduct experiments on <code class=\"docutils literal\"><span class=\"pre\">Metro_Shanghai</span></code> dataset and use the <a class=\"reference external\" href=\"https://uctb.github.io/UCTB/md_file/all_results.html#stmeta-version\">STMeta_V1</a> to model both &quot;Distance-Correlation-Line&quot; graph and &quot;Distance-Correlation-Line-TopK&quot; and the results are following:</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\"><strong>Metro: Shanghai</strong></th>\n<th align=\"center\">Graph</th>\n<th align=\"center\">Test-RMSE</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">STMeta_V1</td>\n<td align=\"center\">Distance-Correlation-Line</td>\n<td align=\"center\">153.17</td>\n</tr>\n<tr>\n<td align=\"center\">STMeta_V1</td>\n<td align=\"center\">Distance-Correlation-Line-TopK</td>\n<td align=\"center\">140.82</td>\n</tr>\n</tbody>\n</table><p>The results show that the performance of STMeta_V1 with the graph &quot;Distance-Correlation-Line-TopK&quot; is better than &quot;Distance-Correlation-Line&quot; model and the RMSE is reduced by about 12.4%, which validates the effectiveness of the topk graph for spatiotemporal modeling STMeta algorithm.</p>\n<hr class=\"docutils\" />\n<p><u><a class=\"reference external\" href=\"../index.html\">Back To HomePage</a></u></p>\n</div>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"visualization_tool.html\" class=\"btn btn-neutral float-right\" title=\"5. Visualization-tool\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"urban_dataset.html\" class=\"btn btn-neutral\" title=\"3. Urban Datasets\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/md_file/src/image/README.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>&lt;no title&gt; &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../../../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../../../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../../../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../../../index.html\"/> \n\n  \n  <script src=\"../../../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../../../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../../../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../../../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../../../index.html\">Docs</a> &raquo;</li>\n        \n      <li>&lt;no title&gt;</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../../../_sources/md_file/src/image/README.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <p>Image resources</p>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../../../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../../../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/md_file/static/stable_test.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Stable Test Records &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../../index.html\"/> \n\n  \n  <script src=\"../../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../../index.html\">Docs</a> &raquo;</li>\n        \n      <li>Stable Test Records</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../../_sources/md_file/static/stable_test.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"stable-test-records\">\n<h1>Stable Test Records<a class=\"headerlink\" href=\"#stable-test-records\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"didi-chengdu\">\n<h2>DiDi Chengdu<a class=\"headerlink\" href=\"#didi-chengdu\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"parameters-for-building-graph\">\n<h3>Parameters for building graph<a class=\"headerlink\" href=\"#parameters-for-building-graph\" title=\"Permalink to this headline\">¶</a></h3>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">Notation</th>\n<th align=\"center\">explanation</th>\n<th align=\"center\">value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">TD</td>\n<td align=\"center\">threshold of distance graph</td>\n<td align=\"center\">7500m</td>\n</tr>\n<tr>\n<td align=\"center\">TI</td>\n<td align=\"center\">threshold of interaction graph</td>\n<td align=\"center\">30</td>\n</tr>\n<tr>\n<td align=\"center\">TC</td>\n<td align=\"center\">threshold of correlation graph</td>\n<td align=\"center\">0.65</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"parameters-for-building-model\">\n<h3>Parameters for building model<a class=\"headerlink\" href=\"#parameters-for-building-model\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-json\"><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n    <span class=\"nt\">&quot;L&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;PT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;lr&quot;</span><span class=\"p\">:</span> <span class=\"mf\">5e-05</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">4</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DenseUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">32</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;LSTMUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;ESlength&quot;</span><span class=\"p\">:</span> <span class=\"mi\">500</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;patience&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Normalize&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;True&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TI&quot;</span><span class=\"p\">:</span> <span class=\"mf\">30.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">6</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;K&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALHeads&quot;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Graph&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Distance-Interaction-Correlation&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GLL&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span>\n<span class=\"p\">}</span>\n</pre></div>\n</div>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">实验编号</th>\n<th align=\"center\">模型版本含义</th>\n<th align=\"center\">Test-RMSE值</th>\n<th align=\"center\">Test-MAPE</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">6.98410</td>\n<td align=\"center\">0.35470</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.06971</td>\n<td align=\"center\">0.36585</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.00403</td>\n<td align=\"center\">0.34867</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.04557</td>\n<td align=\"center\">0.34797</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.05717</td>\n<td align=\"center\">0.36398</td>\n</tr>\n<tr>\n<td align=\"center\">6</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">6.97287</td>\n<td align=\"center\">0.34735</td>\n</tr>\n<tr>\n<td align=\"center\">7</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.03885</td>\n<td align=\"center\">0.35656</td>\n</tr>\n<tr>\n<td align=\"center\">8</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.09894</td>\n<td align=\"center\">0.36024</td>\n</tr>\n<tr>\n<td align=\"center\">9</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.02147</td>\n<td align=\"center\">0.33930</td>\n</tr>\n<tr>\n<td align=\"center\">均值、标准差</td>\n<td align=\"center\"></td>\n<td align=\"center\">均值 7.03252，标准差 0.03865</td>\n<td align=\"center\"></td>\n</tr>\n<tr>\n<td align=\"center\">平均耗时</td>\n<td align=\"center\"></td>\n<td align=\"center\">0.5h~1.5h</td>\n<td align=\"center\"></td>\n</tr>\n</tbody>\n</table></div>\n</div>\n<div class=\"section\" id=\"didi-xian\">\n<h2>DiDi Xian<a class=\"headerlink\" href=\"#didi-xian\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"highlight-json\"><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n    <span class=\"nt\">&quot;TrainDays&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DenseUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">32</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Graph&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Distance-Interaction-Correlation&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">6</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Train&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;False&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Dataset&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;DiDi&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GLL&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TD&quot;</span><span class=\"p\">:</span> <span class=\"mf\">7500.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALHeads&quot;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;patience&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Epoch&quot;</span><span class=\"p\">:</span> <span class=\"mi\">10000</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CodeVersion&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ST0&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">4</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TC&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.65</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Device&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;L&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;PT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;ESlength&quot;</span><span class=\"p\">:</span> <span class=\"mi\">500</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;LSTMUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TI&quot;</span><span class=\"p\">:</span> <span class=\"mf\">30.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Normalize&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;True&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;City&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Xian&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;lr&quot;</span><span class=\"p\">:</span> <span class=\"mf\">5e-05</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DataRange&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;BatchSize&quot;</span><span class=\"p\">:</span> <span class=\"mi\">128</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;K&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Group&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Xian&quot;</span>\n<span class=\"p\">}</span>\n</pre></div>\n</div>\n<p>STMeta-V2 多次实验结果，每次实验耗时 0.5h~1.5h</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">实验编号</th>\n<th align=\"center\">Test-RMSE</th>\n<th align=\"center\">Test-MAPE</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">5.80502</td>\n<td align=\"center\">0.36022</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">5.88970</td>\n<td align=\"center\">0.35590</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">6.00412</td>\n<td align=\"center\">0.45126</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">5.93798</td>\n<td align=\"center\">0.37956</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">6.01064</td>\n<td align=\"center\">0.39242</td>\n</tr>\n<tr>\n<td align=\"center\">6</td>\n<td align=\"center\">5.89309</td>\n<td align=\"center\">0.40803</td>\n</tr>\n<tr>\n<td align=\"center\">7</td>\n<td align=\"center\">5.84786</td>\n<td align=\"center\">0.35915</td>\n</tr>\n<tr>\n<td align=\"center\">8</td>\n<td align=\"center\">5.88188</td>\n<td align=\"center\">0.36777</td>\n</tr>\n<tr>\n<td align=\"center\">9</td>\n<td align=\"center\">5.97407</td>\n<td align=\"center\">0.42393</td>\n</tr>\n<tr>\n<td align=\"center\">10</td>\n<td align=\"center\">5.80497</td>\n<td align=\"center\">0.37014</td>\n</tr>\n</tbody>\n</table><p>最终结果：Test-RMSE 均值 5.90493，标准差 0.07142</p>\n<p>Metro Shanghai</p>\n<div class=\"highlight-json\"><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n    <span class=\"nt\">&quot;TrainDays&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;patience&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Train&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;False&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">4</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;City&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ShanghaiV1&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;ESlength&quot;</span><span class=\"p\">:</span> <span class=\"mi\">500</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;K&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GLL&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;LSTMUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Normalize&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;True&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;PT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Epoch&quot;</span><span class=\"p\">:</span> <span class=\"mi\">10000</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TI&quot;</span><span class=\"p\">:</span> <span class=\"mf\">100.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;lr&quot;</span><span class=\"p\">:</span> <span class=\"mf\">2e-05</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Dataset&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Metro&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DenseUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">32</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;L&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Group&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Shanghai&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Graph&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Distance-line-Correlation&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DataRange&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALHeads&quot;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CodeVersion&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ST_Sim_0&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">6</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TD&quot;</span><span class=\"p\">:</span> <span class=\"mf\">5000.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TC&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.7</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;BatchSize&quot;</span><span class=\"p\">:</span> <span class=\"mi\">128</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Device&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1&quot;</span>\n<span class=\"p\">}</span>\n</pre></div>\n</div>\n<p>STMeta-V2 多次实验结果，每次实验耗时 6.5h~7.5h</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">实验编号</th>\n<th align=\"center\">Test-RMSE</th>\n<th align=\"center\">Test-MAPE</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">148.88104</td>\n<td align=\"center\">0.13178</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">149.58350</td>\n<td align=\"center\">0.14325</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">168.16162</td>\n<td align=\"center\">0.14498</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">155.88750</td>\n<td align=\"center\">0.19575</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">155.09171</td>\n<td align=\"center\">0.18060</td>\n</tr>\n<tr>\n<td align=\"center\">6</td>\n<td align=\"center\">166.13303</td>\n<td align=\"center\">0.18040</td>\n</tr>\n<tr>\n<td align=\"center\">7</td>\n<td align=\"center\">157.08799</td>\n<td align=\"center\">0.15245</td>\n</tr>\n</tbody>\n</table><p>最终结果：Test-RMSE 均值 157.26091，标准差 6.90058</p>\n</div>\n<div class=\"section\" id=\"chargestation-beijing\">\n<h2>ChargeStation Beijing<a class=\"headerlink\" href=\"#chargestation-beijing\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"highlight-json\"><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n    <span class=\"nt\">&quot;GALUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TD&quot;</span><span class=\"p\">:</span> <span class=\"mf\">1000.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TI&quot;</span><span class=\"p\">:</span> <span class=\"mf\">500.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;K&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Train&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;False&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">6</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;patience&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;ESlength&quot;</span><span class=\"p\">:</span> <span class=\"mi\">200</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Graph&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Distance-Correlation&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Normalize&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;True&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;lr&quot;</span><span class=\"p\">:</span> <span class=\"mf\">2e-05</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Device&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;BatchSize&quot;</span><span class=\"p\">:</span> <span class=\"mi\">128</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;LSTMUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;City&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Beijing&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TrainDays&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CodeVersion&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ST_Sim1_0&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">4</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALHeads&quot;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DenseUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">32</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;PT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Group&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Beijing&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;L&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DataRange&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TC&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Epoch&quot;</span><span class=\"p\">:</span> <span class=\"mi\">10000</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Dataset&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ChargeStation&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GLL&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span>\n<span class=\"p\">}</span>\n</pre></div>\n</div>\n<p>STMeta-V2 多次实验结果 (暂时只跑了4次)，每次实验耗时约 10h</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">实验编号</th>\n<th align=\"center\">Test-RMSE</th>\n<th align=\"center\">Test-MAPE</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">0.80954</td>\n<td align=\"center\">0.22925</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">0.82956</td>\n<td align=\"center\">0.23242</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">0.82393</td>\n<td align=\"center\">0.22467</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">0.81360</td>\n<td align=\"center\">0.22932</td>\n</tr>\n</tbody>\n</table><p>最终结果：Test-RMSE 均值 0.81915，标准差 0.0079745</p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/md_file/static/transfer_record.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Check-In与POI数据处理方法 &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../../index.html\"/> \n\n  \n  <script src=\"../../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../../index.html\">Docs</a> &raquo;</li>\n        \n      <li>Check-In与POI数据处理方法</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../../_sources/md_file/static/transfer_record.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"check-inpoi\">\n<h1>Check-In与POI数据处理方法<a class=\"headerlink\" href=\"#check-inpoi\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"id1\">\n<h2>数据详情<a class=\"headerlink\" href=\"#id1\" title=\"Permalink to this headline\">¶</a></h2>\n<ol class=\"simple\">\n<li>时间范围：Apr 2012 ~ Sept 2013</li>\n<li>三个城市的POI数量与check-in数量</li>\n</ol>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">城市</th>\n<th align=\"center\">POI数量(计算城市中心为原点、半径为50km的POI数量)</th>\n<th align=\"center\">日均check-in数量(粗略计算所有站点附近1km的checkin数量总和)</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">NYC</td>\n<td align=\"center\">71310</td>\n<td align=\"center\">工作日11707，节假日11358</td>\n</tr>\n<tr>\n<td align=\"center\">Chicago</td>\n<td align=\"center\">21949</td>\n<td align=\"center\">工作日2549，节假日2692</td>\n</tr>\n<tr>\n<td align=\"center\">DC</td>\n<td align=\"center\">21087</td>\n<td align=\"center\">工作日6049，节假日5450</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"check-in\">\n<h2>Check-In 特征计算方法<a class=\"headerlink\" href=\"#check-in\" title=\"Permalink to this headline\">¶</a></h2>\n<p>计算 2013-07-15 到 2013-09-15 之间，各个自行车站点附近1km的checkin总数量，按照工作日和节假日分开，即每个站点的特征维度为48，分别为工作日、节假日的24小时checkin</p>\n</div>\n<div class=\"section\" id=\"poi\">\n<h2>POI特征计算方法<a class=\"headerlink\" href=\"#poi\" title=\"Permalink to this headline\">¶</a></h2>\n<p>一共有428种POI，每个站点统计附近1km出现的POI类型，即每个站点有428维特征</p>\n</div>\n<div class=\"section\" id=\"id2\">\n<h2>特征相似度方法<a class=\"headerlink\" href=\"#id2\" title=\"Permalink to this headline\">¶</a></h2>\n<p>Cosine Similarity</p>\n</div>\n</div>\n<div class=\"section\" id=\"id3\">\n<h1>使用Check-In数据进行相似站点的匹配<a class=\"headerlink\" href=\"#id3\" title=\"Permalink to this headline\">¶</a></h1>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">SD</th>\n<th align=\"center\">TD</th>\n<th align=\"center\">transfer-ratio</th>\n<th align=\"center\">TD-训练样本数量</th>\n<th align=\"center\">TD-Direct</th>\n<th align=\"center\">TD-FT</th>\n<th align=\"center\">TD-Transfer</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>5.15155</strong></td>\n<td align=\"center\">8.97297</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83186</strong></td>\n<td align=\"center\">5.60889</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.79484</strong></td>\n<td align=\"center\">4.86073</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83927</strong></td>\n<td align=\"center\">5.09481</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\"><strong>3.65903</strong></td>\n<td align=\"center\">3.67704</td>\n<td align=\"center\">35.02312</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.38682</strong></td>\n<td align=\"center\">4.10283</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.39081</strong></td>\n<td align=\"center\">3.44701</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.16186</strong></td>\n<td align=\"center\">3.36458</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>6.19588</strong></td>\n<td align=\"center\">8.28328</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.57436</strong></td>\n<td align=\"center\">5.89025</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.54711</strong></td>\n<td align=\"center\">5.64965</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.26407</strong></td>\n<td align=\"center\">6.34057</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.87629</strong></td>\n<td align=\"center\">5.78612</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\"><strong>4.32390</strong></td>\n<td align=\"center\">4.99620</td>\n<td align=\"center\">4.85723</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.26380</strong></td>\n<td align=\"center\">3.38408</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.15168</strong></td>\n<td align=\"center\">3.27858</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>4.43069</strong></td>\n<td align=\"center\">12.75022</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.94628</strong></td>\n<td align=\"center\">4.34232</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.93868</strong></td>\n<td align=\"center\">4.52421</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\">3.46738</td>\n<td align=\"center\"><strong>3.44230</strong></td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.58924</strong></td>\n<td align=\"center\">4.46261</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.29204</strong></td>\n<td align=\"center\">4.51947</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.22782</strong></td>\n<td align=\"center\">3.44588</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.09117</strong></td>\n<td align=\"center\">3.17292</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"id4\">\n<h1>使用POI信息进行相似站点匹配<a class=\"headerlink\" href=\"#id4\" title=\"Permalink to this headline\">¶</a></h1>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">SD</th>\n<th align=\"center\">TD</th>\n<th align=\"center\">transfer-ratio</th>\n<th align=\"center\">TD-训练样本数量</th>\n<th align=\"center\">TD-Direct</th>\n<th align=\"center\">TD-FT</th>\n<th align=\"center\">TD-Transfer</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>5.15155</strong></td>\n<td align=\"center\">7.74238</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83186</strong></td>\n<td align=\"center\">5.22502</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.79484</strong></td>\n<td align=\"center\">5.14237</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83927</strong></td>\n<td align=\"center\">5.11173</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\"><strong>3.65903</strong></td>\n<td align=\"center\">3.67704</td>\n<td align=\"center\">42.10733</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.38682</strong></td>\n<td align=\"center\">4.01524</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.39081</strong></td>\n<td align=\"center\">3.80654</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.16186</strong></td>\n<td align=\"center\">3.40228</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>6.19588</strong></td>\n<td align=\"center\">9.68558</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.57436</strong></td>\n<td align=\"center\">6.06141</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.54711</strong></td>\n<td align=\"center\">5.64207</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.26407</strong></td>\n<td align=\"center\">5.95202</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.87629</strong></td>\n<td align=\"center\">7.71124</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\"><strong>4.32390</strong></td>\n<td align=\"center\">4.99620</td>\n<td align=\"center\">5.20308</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.26380</strong></td>\n<td align=\"center\">3.41202</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.15168</strong></td>\n<td align=\"center\">3.36520</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>4.43069</strong></td>\n<td align=\"center\">8.70660</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.94628</strong></td>\n<td align=\"center\">4.68907</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.93868</strong></td>\n<td align=\"center\">4.71885</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.46738</strong></td>\n<td align=\"center\">3.54126</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.58924</strong></td>\n<td align=\"center\">4.54878</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.29204</strong></td>\n<td align=\"center\">6.51714</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.22782</strong></td>\n<td align=\"center\">3.50503</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.09117</strong></td>\n<td align=\"center\">3.35844</td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">SD</th>\n<th align=\"center\">TD</th>\n<th align=\"center\">transfer-ratio</th>\n<th align=\"center\">TD-训练样本数量</th>\n<th align=\"center\">TD-Direct</th>\n<th align=\"center\">TD-FT</th>\n<th align=\"center\">TD-Transfer</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>5.15155</strong></td>\n<td align=\"center\">8.01029</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83186</strong></td>\n<td align=\"center\">5.52622</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.79484</strong></td>\n<td align=\"center\">5.30417</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83927</strong></td>\n<td align=\"center\">6.07645</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.93593</strong></td>\n<td align=\"center\">5.96554</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\"><strong>3.65903</strong></td>\n<td align=\"center\">3.67704</td>\n<td align=\"center\">46.02469</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.38682</strong></td>\n<td align=\"center\">4.22828</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.39081</strong></td>\n<td align=\"center\">4.37432</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.16186</strong></td>\n<td align=\"center\">3.56052</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.12768</strong></td>\n<td align=\"center\">3.39922</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>4.43069</strong></td>\n<td align=\"center\">11.41116</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.94628</strong></td>\n<td align=\"center\">4.55703</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.93868</strong></td>\n<td align=\"center\">4.31149</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.46738</strong></td>\n<td align=\"center\">3.59811</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.37643</strong></td>\n<td align=\"center\">3.48236</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.58924</strong></td>\n<td align=\"center\">5.95973</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.29204</strong></td>\n<td align=\"center\">5.09110</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.22782</strong></td>\n<td align=\"center\">4.01670</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.09117</strong></td>\n<td align=\"center\">3.34005</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.02813</strong></td>\n<td align=\"center\">3.31671</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>6.19588</strong></td>\n<td align=\"center\">9.18276</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.57436</strong></td>\n<td align=\"center\">5.94807</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.54711</strong></td>\n<td align=\"center\">6.02357</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.26407</strong></td>\n<td align=\"center\">6.02906</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.21905</strong></td>\n<td align=\"center\">5.96555</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.87629</strong></td>\n<td align=\"center\">5.75511</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\"><strong>4.32390</strong></td>\n<td align=\"center\">4.99620</td>\n<td align=\"center\">7.56254</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.26380</strong></td>\n<td align=\"center\">4.44143</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.15168</strong></td>\n<td align=\"center\">3.65643</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.13602</strong></td>\n<td align=\"center\">3.25901</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"transfer\">\n<h1>分析Transfer效果在城市中的分布<a class=\"headerlink\" href=\"#transfer\" title=\"Permalink to this headline\">¶</a></h1>\n<p>绿色的点表示transfer效果好于finetune，红色代表差于finetune</p>\n<div class=\"section\" id=\"target-city-dc\">\n<h2>Target City DC<a class=\"headerlink\" href=\"#target-city-dc\" title=\"Permalink to this headline\">¶</a></h2>\n<p>左侧为 Chicago=&gt;DC，Overall result ：Finetune 3.13602，Transfer 3.25901</p>\n<p>右侧为 NYC=&gt;DC，Overall result ：Finetune 3.02813，Transfer 3.31671</p>\n<p><img alt=\"1567254312266\" src=\"md_file/static/..%5Csrc%5Cimage%5Ctransfer_dc.png\" /></p>\n</div>\n<div class=\"section\" id=\"target-city-nyc\">\n<h2>Target City NYC<a class=\"headerlink\" href=\"#target-city-nyc\" title=\"Permalink to this headline\">¶</a></h2>\n<p>左侧为 DC =&gt; NYC，Overall result ：Finetune 4.93593，Transfer 5.96554</p>\n<p>右侧为 Chicago =&gt;NYC，Overall result ：Finetune 5.21905，Transfer 5.96555</p>\n<p><img alt=\"1567253682671\" src=\"md_file/static/..%5Csrc%5Cimage%5Ctransfer_nyc.png\" /></p>\n</div>\n<div class=\"section\" id=\"target-city-chicago\">\n<h2>Target City Chicago<a class=\"headerlink\" href=\"#target-city-chicago\" title=\"Permalink to this headline\">¶</a></h2>\n<p>左侧为 NYC=&gt;Chicago，Overall result ：Finetune 3.37643，Transfer 3.48236</p>\n<p>右侧为 DC=&gt;Chicago，Overall result ：Finetune 3.12768，Transfer 3.39922</p>\n<p><img alt=\"1567255183794\" src=\"md_file/static/..%5Csrc%5Cimage%5Ctransfer_chicago.png\" /></p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/md_file/uctb_group.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>8. About us (UCTB Group) &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"prev\" title=\"7. Benchmark\" href=\"all_results.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">8. About us (UCTB Group)</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#pi\">8.1. PI</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#key-contributors\">8.2. Key Contributors</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#past-contributors\">8.3. Past Contributors</a></li>\n</ul>\n</li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>8. About us (UCTB Group)</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/uctb_group.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"about-us-uctb-group\">\n<h1>8. About us (UCTB Group)<a class=\"headerlink\" href=\"#about-us-uctb-group\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"pi\">\n<h2>8.1. PI<a class=\"headerlink\" href=\"#pi\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Leye Wang</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Feb</span> <span class=\"pre\">2019,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Assistant professor &#64; Key Lab of High Confidence Software Technologies, Department of Computer Science &amp; Technology, Peking University.</p>\n<p>Email: <a class=\"reference external\" href=\"mailto:leyewang&#37;&#52;&#48;pku&#46;edu&#46;cn\">leyewang<span>&#64;</span>pku<span>&#46;</span>edu<span>&#46;</span>cn</a></p>\n<p><a class=\"reference external\" href=\"https://cs.pku.edu.cn/info/1174/2334.htm\">Leye Wang's HomePage</a></p>\n<hr class=\"docutils\" />\n<p><strong>Longbiao Chen</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">March</span> <span class=\"pre\">2022,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Associate professor &#64; Department of Computer Science, Xiamen University, China</p>\n<p>Email: <a class=\"reference external\" href=\"mailto:longbiaochen&#37;&#52;&#48;xmu&#46;edu&#46;cn\">longbiaochen<span>&#64;</span>xmu<span>&#46;</span>edu<span>&#46;</span>cn</a></p>\n<p><a class=\"reference external\" href=\"https://longbiao.crowdsensing.cn/\">Longbiao Chen's HomePage</a></p>\n</div>\n<div class=\"section\" id=\"key-contributors\">\n<h2>8.2. Key Contributors<a class=\"headerlink\" href=\"#key-contributors\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Di Chai</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Feb</span> <span class=\"pre\">2019,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Ph.D student in computer science and engineering at Hong Kong University of Science and Technology.</p>\n<p>Email: dchai&#64;cse.ust.hk</p>\n<hr class=\"docutils\" />\n<p><strong>Liyue Chen</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Nov</span> <span class=\"pre\">2019,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Ph.D student in Peking University.</p>\n<p>Email:  chenliyue2019&#64;gmail.com</p>\n<hr class=\"docutils\" />\n<p><strong>Jiangyi Fang</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">April</span> <span class=\"pre\">2022,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Undergraduate student majored in Automation in Huazhong University of Science and Technology.</p>\n<p>Email:  fangjiangyi2001&#64;gmail.com</p>\n<hr class=\"docutils\" />\n<p><strong>Yayao Hong</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Sep</span> <span class=\"pre\">2022,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Master student in Fujian Key Laboratory of Sensing and Computing for Smart Cities at Xiamen University.</p>\n<p>Email:  hyymmmint&#64;stu.xmu.edu.cn</p>\n<hr class=\"docutils\" />\n<p><strong>Tengfei Liu</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">March</span> <span class=\"pre\">2023,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Undergraduate student in computer science and technology at China University of Geosciences.</p>\n<p>Email:  tf66366&#64;cug.edu.cn</p>\n<hr class=\"docutils\" />\n<p><strong>Xiuhuai Xie</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">July</span> <span class=\"pre\">2023,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Postgraduate student majored in Computer Technology in Xiamen University.\nEmail: trafalgar2001&#64;163.com</p>\n</div>\n<div class=\"section\" id=\"past-contributors\">\n<h2>8.3. Past Contributors<a class=\"headerlink\" href=\"#past-contributors\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Hang Zhu</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">March</span> <span class=\"pre\">2022,</span> <span class=\"pre\">Jul</span> <span class=\"pre\">2023.</span></code></p>\n<p>Master student in Fujian Key Laboratory of Sensing and Computing for Smart Cities at Xiamen University.</p>\n<p>Email:  zhuhang&#64;stu.xmu.edu.cn</p>\n<hr class=\"docutils\" />\n<p><strong>Jin Xu</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Jul</span> <span class=\"pre\">2019</span> <span class=\"pre\">to</span> <span class=\"pre\">Aug</span> <span class=\"pre\">2019.</span></code></p>\n<p>Undergraduate student in Peking University majoring in Data Science and Big Data Technology.</p>\n<p>Email: jinxu&#64;pku.edu.cn</p>\n<hr class=\"docutils\" />\n<p><strong>Wenjie Yang</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Nov</span> <span class=\"pre\">2019</span> <span class=\"pre\">to</span> <span class=\"pre\">Aug</span> <span class=\"pre\">2020.</span></code></p>\n<p>Master student in computer science and engineering at Hong Kong University of Science and Technology.</p>\n<p>Email: wjyccs&#64;gmail.com</p>\n<hr class=\"docutils\" />\n<p><strong>Xueqiao Xu</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Jan</span> <span class=\"pre\">2020</span> <span class=\"pre\">to</span> <span class=\"pre\">Jul</span> <span class=\"pre\">2020.</span></code></p>\n<p>He got his bachelor' degree in Peking University majoring in Data Science and Big Data Technology.</p>\n<p>Email:  snowbridge&#64;foxmail.com</p>\n<hr class=\"docutils\" />\n<p><strong>Zhenyu Cui</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">May</span> <span class=\"pre\">2020</span> <span class=\"pre\">to</span> <span class=\"pre\">Nov</span> <span class=\"pre\">2020.</span></code></p>\n<p>Graduate student in University of Chinese Academy of Sciences, majoring in Computer Vision and Deep Learning.</p>\n<p>Email:  cuizhenyu18&#64;mails.ucas.ac.cn</p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n      \n        <a href=\"all_results.html\" class=\"btn btn-neutral\" title=\"7. Benchmark\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/md_file/urban_dataset.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>3. Urban Datasets &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"4. Predictive Tool\" href=\"predictive_tool.html\"/>\n        <link rel=\"prev\" title=\"2. Installation\" href=\"installation.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">3. Urban Datasets</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#datasets-overview\">3.1. Datasets Overview</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#bike-datasets\">3.2. Bike Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#bus-datasets\">3.3. Bus Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#speed-datasets\">3.4. Speed Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#pedestrian-datasets\">3.5. Pedestrian Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#taxi-datasets\">3.6. Taxi Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#metro-datasets\">3.7. Metro Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#flow-speed-datasets\">3.8. Flow Speed Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#load-uctb-dataset\">3.9. Load UCTB Dataset</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#dataset-format\">3.9.1. Dataset format</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#use-datasets-from-urban-datasets\">3.9.2. Use datasets from Urban Datasets</a></li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#how-to-get-the-datasets-at-other-granularities\">3.10. How to get the datasets at other granularities?</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#build-your-own-datasets\">3.11. Build your own datasets</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>3. Urban Datasets</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/urban_dataset.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"urban-datasets\">\n<h1>3. Urban Datasets<a class=\"headerlink\" href=\"#urban-datasets\" title=\"Permalink to this headline\">¶</a></h1>\n<p>UCTB is designed for urban computing in various scenarios. Currently, It releases <a class=\"reference external\" href=\"https://github.com/uctb/Urban-Dataset\">a public dataset repository</a> including bike sharing, ride sharing, traffic speed, and pedestrian counting applications. <strong>If you are interested in this project, making a contribution to the dataset is strongly welcomed :)</strong></p>\n<div class=\"section\" id=\"datasets-overview\">\n<h2>3.1. Datasets Overview<a class=\"headerlink\" href=\"#datasets-overview\" title=\"Permalink to this headline\">¶</a></h2>\n<p>Currently, UCTB offers the following datasets in 7 scenarios, with detailed information provided in the table below. We are constantly working to release more datasets in the future.</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\"><strong>Application</strong></th>\n<th align=\"center\"><strong>City</strong></th>\n<th align=\"center\"><strong>Time Range</strong></th>\n<th align=\"center\"><strong>Temporal Granularity</strong></th>\n<th align=\"center\"><strong>Dataset Link</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip\">66.0M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">Chicago</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip\">30.2M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">DC</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip\">31.0M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Pedestrian Count</td>\n<td align=\"center\">Melbourne</td>\n<td align=\"center\">2021.01.01-2022.11.01</td>\n<td align=\"center\">60 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip\">1.18M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Vehicle Speed</td>\n<td align=\"center\">LA</td>\n<td align=\"center\">2012.03.01-2012.06.28</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip\">11.8M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Vehicle Speed</td>\n<td align=\"center\">BAY</td>\n<td align=\"center\">2017.01.01-2017.07.01</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip\">27.9M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Taxi Demand</td>\n<td align=\"center\">Chicago</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip\">6.1M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bus</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2022.02.01-2024.01.13</td>\n<td align=\"center\">60 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip\">4.89M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Metro</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2022.02.01-2023.12.21</td>\n<td align=\"center\">60 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip\">11.3M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Traffic Flow</td>\n<td align=\"center\">Luzern</td>\n<td align=\"center\">2015.01.01-2016.01.01</td>\n<td align=\"center\">3 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Flow/3_minutes/Flow_Luzern.zip\">21M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">Chicago (community)</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip\">6.06</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">Chicago (census tract)</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip\">10M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2009.01.01-2023.06.01</td>\n<td align=\"center\">5 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/5_minutes/Taxi_NYC.zip\">36.9M</a></td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"bike-datasets\">\n<h2>3.2. Bike Datasets<a class=\"headerlink\" href=\"#bike-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The bike-sharing datasets are collected from U.S. open data portals including New York City (NYC, https://www.citibikenyc.com/system-data), Chicago (CHI, https://www.divvybikes.com/system-data), and DC (https://www.capitalbikeshare.com/system-data). The dataset time span for all three cities is more than four years. The total number of historical flow records is around 49 million, 13 million, and 14 million in NYC, Chicago, and DC, respectively, and each record contains the start station, start time, stop station, stop time, etc.</p>\n<p>The following shows the map visualization of bike stations in NYC, Chicago, and DC.</p>\n<div style=\"display: flex;\">\n  <img src=\"https://camo.githubusercontent.com/eb6a2130ac83330fa6e79276f561c3966c79b7cc90b6cba5b79980127faaa316/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f4e59432e6a7067\" alt=\"图片1\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/9bb00c6ffb052701433ec46dfe52e96365014a2aa3eab825dc4f52e319ff3d1d/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f4368696361676f2e6a7067\" alt=\"图片2\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/a57455f9f9ccba9ed12ec57b3d5d805d75f4577278c824834ea429dc844cf976/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f44432e6a7067\" alt=\"图片3\" style=\"flex: 1; max-width: 300px; height: auto;\">\n</div>\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Bike/</div>\n<div class=\"section\" id=\"bus-datasets\">\n<h2>3.3. Bus Datasets<a class=\"headerlink\" href=\"#bus-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The bus datasets are collected from DATA.NY.GOV: MTA Bus Hourly Ridership. This dataset is provided by the Metropolitan Transportation Authority and is available for public download. It offers bus ridership estimates on an hourly basis by bus route. Data collection started from February 2022 and has been regularly updated. The Bus_NYC dataset includes data up to January 13, 2024. The latest version can be accessed on the website mentioned above. The station info data is downloaded from NYU | Faculty Digital Archive: New York City Bus Routes, Dec 2019. It does not encompass all bus routes. So we discarded the traffic data for bus routes where station information was not found, ultimately retaining 226 bus routes.\nFollowing shows the map-visualization of Bus_NYC datasets.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Bus.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Data catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Bus</p>\n</div>\n<div class=\"section\" id=\"speed-datasets\">\n<h2>3.4. Speed Datasets<a class=\"headerlink\" href=\"#speed-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The two traffic speed datasets are widely used in STTP research: METR-LA and PEMS-BAY from Los Angeles (LA) County and Bay Area, respectively. In METR-LA, 207 sensors record highway vehicles’ speeds for four months; In PEMS-BAY, there are 325 sensors for six months. Each sensor can be seen as a station.</p>\n<p>Following shows the map-visualization of METR-LA and PEMS-BAY.</p>\n<div style=\"display: flex;\">\n  <img src=\"https://camo.githubusercontent.com/7beb63775a5bcd043923b5b749896af2d10358bc30e2c974f07a882e5b70b20a/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f4d4554525f4c412e706e67\" alt=\"图片1\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/091bdeb27f8c007a2b19adfe23c48e072d90f157cd033932dbd773cb47c55dad/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f50454d535f4241592e706e67\" alt=\"图片2\" style=\"flex: 1; max-width: 300px; height: auto;\">\n</div>\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Speed/</div>\n<div class=\"section\" id=\"pedestrian-datasets\">\n<h2>3.5. Pedestrian Datasets<a class=\"headerlink\" href=\"#pedestrian-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The pedestrian datasets are collected from open data website of Melbourne. The full datasets' timespan is over 10 years and the datasets are still being updated at a fixed frequency (i.e., 60 minutes). Due to the fact that some sites were not set up in the early days and some sites lacked data, we only choose about a year in temporal dimension and 55 stations in spatial dimension. There is also accessible information about sensors on the same website. In the dataset of sensor information, we obtain the name, the sensor's ID, the sensor's status(whether it is active or not), the latitude and longtitude of each sensor.\nFollowing shows the map-visualization of Pedestrian datasets in Melbourne.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Pedestrain_Melbourne.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Data catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Pedestrian</p>\n</div>\n<div class=\"section\" id=\"taxi-datasets\">\n<h2>3.6. Taxi Datasets<a class=\"headerlink\" href=\"#taxi-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The Taxi datasets are collected from the city of Chicago's open data portal and the city of New York's open data portal, where you are able to freely download Chicago city's and NYC's datasets for your own analysis. The datasets record taxi trips from these dimensions listed below: pickup and dropoff time, pickup and dropoff location, fee etc. In our dataset, we only consider the pickup info of each record. You can conduct more comprehensive analysis with the help of our datasets and the website.</p>\n<p>Taxi Chicago Dataset\nFacts in dataset description</p>\n<p>There are two candidate spatial discretization information: census tract and community area.\nFor each record, it will aggregate census tract granularity into community area due to privacy preserve.\nWhich granularity to choose</p>\n<p>Thus, we need to choose a proper granularity. According to the needs of downstream tasks (Spatio-temporal traffic prediction), we summarize two principles of spatial granularity selection:</p>\n<p>Spatial granularity as small as possible (especially in high-demand area).\nDemamd aggregated due to privacy as few as possible.\nOn one hand, time distribution of taxi demand in downtown is dense, and the probability of being aggregated is small. on the other hand, the time distribution of taxi demand in the suburbs is sparse, and the probability of being aggregated is high.</p>\n<p>Final datasets we open</p>\n<p>We finally choose to process two datasets: one is Taxi_Chicago, where only spatial granularity community area is used; another is Taxi_fine_grained_Chicago, where community area is used in suburbs while census tract is used in downtown.</p>\n<p>We highly recommend that you conduct more analysis on Taxi_fine_grained_Chicago. By the way, we have adopted a special operation that taxi demand of specific census tract in 15-minute time window equal or less than 2 will be set 2. This operation won't affect much because all of aggregation situation is ultimately caused by insufficient demand.</p>\n<p>Following shows the map-visualization of Taxi_Chicago datasets.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Chicago_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Following shows the map-visualization of Taxi_fine_grained_Chicago datasets.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Chicago_fine_grained_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Taxi NYC Datasets\nWe collect Taxi NYC dataset from these two websites: https://opendata.cityofnewyork.us/ and https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page. We also obtain information of taxi zones in New York from this website. As a result of size of dataset, we put it on the link with extraction code gw6p.</p>\n<p>Following shows the map-visualization of Taxi_NYC datasets.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Data catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Taxi</p>\n</div>\n<div class=\"section\" id=\"metro-datasets\">\n<h2>3.7. Metro Datasets<a class=\"headerlink\" href=\"#metro-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The metro datasets are collected from DATA.NY.GOV: MTA Subway Hourly Ridership. The Metro_NYC dataset is provided by the Metropolitan Transportation Authority and is available for public download. It offers estimates of subway ridership on an hourly basis by subway station complex. Data collection started from February 2022 and has been regularly updated. The Metro_NYC dataset includes data up to December 21, 2023. The latest version can be accessed on the website mentioned above.</p>\n<p>Following shows the map-visualization of station complex in NYC.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Metro.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Data catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Metro</p>\n</div>\n<div class=\"section\" id=\"flow-speed-datasets\">\n<h2>3.8. Flow Speed Datasets<a class=\"headerlink\" href=\"#flow-speed-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The traffic flow datasets are collected from UTD19 - Research Collection. UTD19 is a large-scale traffic data set from over 20000 stationary detectors on urban roads in 40 cities worldwide making it the largest multi-city traffic data set publically available. In our dataset, we only consider the data for the city of Luzern. The dataset enriched location information of sensors with further attributes describing the location of the sensor with respect to the road network.\nFollowing shows the map-visualization of station complex in Luzern.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Luzern_Flow.png\" alt=\"Image\" style=\"max-width: 400px; height: auto;\"><p>Data catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Flow</p>\n</div>\n<div class=\"section\" id=\"load-uctb-dataset\">\n<h2>3.9. Load UCTB Dataset<a class=\"headerlink\" href=\"#load-uctb-dataset\" title=\"Permalink to this headline\">¶</a></h2>\n<!-- TODO: 介绍pickle --><p>The <code class=\"docutils literal\"><span class=\"pre\">pickle</span></code> module is an external library that comes built-in with Python and provides functionality for converting Python objects into a byte stream (serialization) and restoring them back to their original state (deserialization). We use it to help data format instances to transform between memory and disk.</p>\n<div class=\"section\" id=\"dataset-format\">\n<h3>3.9.1. Dataset format<a class=\"headerlink\" href=\"#dataset-format\" title=\"Permalink to this headline\">¶</a></h3>\n<p>We've collected some public datasets and processing them into UCTB dataset format. UCTB dataset is a python build-in dictionary object that could be loaded by pickle package. Here is the example of UCTB dataset.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># Let&#39;s say ``my_dataset`` is your dataset.</span>\n<span class=\"n\">my_dataset</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;TimeRange&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s1\">&#39;YYYY-MM-DD&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;YYYY-MM-DD&#39;</span><span class=\"p\">],</span>\n    <span class=\"s2\">&quot;TimeFitness&quot;</span><span class=\"p\">:</span> <span class=\"mi\">60</span><span class=\"p\">,</span> <span class=\"c1\"># Minutes</span>\n    \n    <span class=\"s2\">&quot;Node&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;TrafficNode&quot;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">,</span> <span class=\"c1\"># With shape [time, num-of-node]</span>\n        <span class=\"s2\">&quot;TrafficMonthlyInteraction&quot;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">,</span> <span class=\"c1\"># With shape [month, num-of-node. num-of-node]</span>\n        <span class=\"s2\">&quot;StationInfo&quot;</span><span class=\"p\">:</span> <span class=\"nb\">list</span> <span class=\"c1\"># elements in it should be [id, build-time, lat, lng, name]</span>\n        <span class=\"s2\">&quot;POI&quot;</span><span class=\"p\">:</span> <span class=\"p\">[]</span>\n    <span class=\"p\">},</span>\n\n    <span class=\"s2\">&quot;Grid&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;TrafficGrid&quot;</span><span class=\"p\">:</span> <span class=\"p\">[],</span>\n        <span class=\"s2\">&quot;GridLatLng&quot;</span><span class=\"p\">:</span> <span class=\"p\">[],</span>\n        <span class=\"s2\">&quot;POI&quot;</span><span class=\"p\">:</span> <span class=\"p\">[]</span>\n    <span class=\"p\">},</span>\n\n    <span class=\"s2\">&quot;ExternalFeature&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n         <span class=\"s2\">&quot;Weather&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"n\">time</span><span class=\"p\">,</span> <span class=\"n\">weather</span><span class=\"o\">-</span><span class=\"n\">feature</span><span class=\"o\">-</span><span class=\"n\">dim</span><span class=\"p\">]</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"use-datasets-from-urban-datasets\">\n<h3>3.9.2. Use datasets from Urban Datasets<a class=\"headerlink\" href=\"#use-datasets-from-urban-datasets\" title=\"Permalink to this headline\">¶</a></h3>\n<p>In this section, we will introduce how to get the dataset from Urban_Dataset and read the dataset using python.</p>\n<p>You are proposed to download the zip file from the <a class=\"reference external\" href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip\">link</a> and unzip the file. Let's say the following scripts are placed at the same directory with the dataset.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">pickle</span> <span class=\"k\">as</span> <span class=\"nn\">pkl</span>\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"n\">data_path</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Pedestrian_Melbourne.pkl&#39;</span>\n<span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"n\">data_path</span><span class=\"p\">,</span><span class=\"s1\">&#39;rb&#39;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">fp</span><span class=\"p\">:</span>\n    <span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">pkl</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"n\">fp</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Take a look at the necessary information about the dataset:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># Traffic data </span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Data time range&#39;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;TimeRange&#39;</span><span class=\"p\">])</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Traffic data shape:&#39;</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficNode&#39;</span><span class=\"p\">]))</span>\n<span class=\"c1\"># The first dimension of data[&#39;Node&#39;][&#39;TrafficNode&#39;] is the length of time-sequence.</span>\n<span class=\"c1\"># The second dimension is the number of stations.</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Time fitness:&#39;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;TimeFitness&#39;</span><span class=\"p\">],</span> <span class=\"s1\">&#39;minutes&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Time sequence length:&#39;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficNode&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Number of stations:&#39;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficNode&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"n\">Data</span> <span class=\"n\">time</span> <span class=\"nb\">range</span> <span class=\"p\">[</span><span class=\"s1\">&#39;2021-01-01&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;2022-11-01&#39;</span><span class=\"p\">]</span>\n<span class=\"n\">Traffic</span> <span class=\"n\">data</span> <span class=\"n\">shape</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"mi\">16056</span><span class=\"p\">,</span> <span class=\"mi\">55</span><span class=\"p\">)</span>\n<span class=\"n\">Time</span> <span class=\"n\">fitness</span><span class=\"p\">:</span> <span class=\"mi\">60</span> <span class=\"n\">minutes</span>\n<span class=\"n\">Time</span> <span class=\"n\">sequence</span> <span class=\"n\">length</span><span class=\"p\">:</span> <span class=\"mi\">16056</span>\n<span class=\"n\">Number</span> <span class=\"n\">of</span> <span class=\"n\">stations</span><span class=\"p\">:</span> <span class=\"mi\">55</span>\n</pre></div>\n</div>\n<p>Visualize the distribution of the traffic data:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">matplotlib.pyplot</span> <span class=\"k\">as</span> <span class=\"nn\">plt</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficNode&#39;</span><span class=\"p\">][:,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n</pre></div>\n</div>\n<p><img alt=\"png\" src=\"../_images/toturial_p1_dataplot.png\" /></p>\n</div>\n</div>\n<div class=\"section\" id=\"how-to-get-the-datasets-at-other-granularities\">\n<h2>3.10. How to get the datasets at other granularities?<a class=\"headerlink\" href=\"#how-to-get-the-datasets-at-other-granularities\" title=\"Permalink to this headline\">¶</a></h2>\n<p>We could merge the fine-grained data to obtain the datasets at other granularities (e.g., by summing the 12 flows from the 5-minutes datasets to obtain 60-minutes datasets). UCTB provides the API to merge data. You could specify MergeIndex and MergeWay in the NodeTrafficLoader and GridTrafficLoader. Here is an example:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n\n<span class=\"c1\"># loading 5-minutes datasets</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s2\">&quot;Bike&quot;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s2\">&quot;NYC&quot;</span><span class=\"p\">)</span> \n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_traffic</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span> <span class=\"c1\"># with shape (446976, 820)</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s2\">&quot;Bike&quot;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s2\">&quot;NYC&quot;</span><span class=\"p\">,</span> <span class=\"n\">MergeIndex</span><span class=\"o\">=</span><span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"n\">MergeWay</span><span class=\"o\">=</span><span class=\"s2\">&quot;sum&quot;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_traffic</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span> <span class=\"c1\"># with shape (37248, 820)</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"build-your-own-datasets\">\n<h2>3.11. Build your own datasets<a class=\"headerlink\" href=\"#build-your-own-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>If you want to apply uctb dataloaders to your dataset, make your dataset compatible with the template as section 3.2.1 shown. And then save it with package <code class=\"docutils literal\"><span class=\"pre\">pickle</span></code> to a local path <code class=\"docutils literal\"><span class=\"pre\">pkl_file_name</span></code>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">pickle</span>\n<span class=\"n\">pkl_file_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;./my_dataset.pkl&#39;</span>  \n<span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"n\">pkl_file_name</span><span class=\"p\">,</span> <span class=\"s1\">&#39;wb&#39;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">handle</span><span class=\"p\">:</span>\n    <span class=\"n\">pickle</span><span class=\"o\">.</span><span class=\"n\">dump</span><span class=\"p\">(</span><span class=\"n\">my_dataset</span><span class=\"p\">,</span> <span class=\"n\">handle</span><span class=\"p\">,</span> <span class=\"n\">protocol</span><span class=\"o\">=</span><span class=\"n\">pickle</span><span class=\"o\">.</span><span class=\"n\">HIGHEST_PROTOCOL</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Finally, you can make uses of your dataset by UCTB's loader APIs:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"n\">pkl_file_name</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Also, we provide interface to help build your own dataset, through which we clarify whether a field is necessary or optional when building a UCTB dataset.</p>\n<p>To build a UCTB dataset, it is necessary to provide variables listed as below.</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\">Variable_name</th>\n<th align=\"left\">Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">time_fitness</td>\n<td align=\"left\">The length of the interval between adjacent slots</td>\n</tr>\n<tr>\n<td align=\"left\">time_range</td>\n<td align=\"left\">The time interval at the beginning and end of the data</td>\n</tr>\n<tr>\n<td align=\"left\">traffic_node</td>\n<td align=\"left\">The spatio-temporal information</td>\n</tr>\n<tr>\n<td align=\"left\">node_satation_info</td>\n<td align=\"left\">The basic information of each data collecting node</td>\n</tr>\n<tr>\n<td align=\"left\">dataset_name</td>\n<td align=\"left\">Name of the dataset</td>\n</tr>\n<tr>\n<td align=\"left\">city</td>\n<td align=\"left\">A variable used to integrate holiday and weather information to traffic data</td>\n</tr>\n</tbody>\n</table><p>Then, use the specified path to save the dataset, otherwise it will be saved in the current run-time path.</p>\n<p>Although it's diffcult to form an integrated function to include all situation you may meet during the transforming process, there are some procedures you might obey to simplify the data preprocessing.</p>\n<ul class=\"simple\">\n<li>Data preprocessing<ol>\n<li>Zero values</li>\n<li>Missing values(NA)</li>\n<li>Unknown values</li>\n<li>Abnormal values</li>\n<li>duplicates</li>\n<li>Statistics(station number and time slots)</li>\n</ol>\n</li>\n<li>Dictionary building<ul>\n<li>Basic information(time range and time fitness)</li>\n<li>Traffic node building<ul>\n<li>Spatio-temporal raster data building<ol>\n<li>Initialization</li>\n<li>iterate raw data table and fill the matrix</li>\n</ol>\n</li>\n<li>Station information</li>\n</ul>\n</li>\n<li>Traffic grid building</li>\n<li>External feature</li>\n</ul>\n</li>\n</ul>\n<p>Now, we assume that you have already finished variable preparation. UCTB provide API to assist you with dataset building.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">build_uctb_dataset</span><span class=\"p\">(</span><span class=\"n\">traffic_node</span><span class=\"o\">=</span><span class=\"n\">traffic_node</span><span class=\"p\">,</span> <span class=\"n\">time_fitness</span><span class=\"o\">=</span><span class=\"n\">time_fitness</span><span class=\"p\">,</span> \n                <span class=\"n\">node_station_info</span><span class=\"o\">=</span><span class=\"n\">node_station_info</span><span class=\"p\">,</span> <span class=\"n\">time_range</span><span class=\"o\">=</span><span class=\"n\">time_range</span><span class=\"p\">,</span> \n                <span class=\"n\">output_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;tmp_dir&#39;</span><span class=\"p\">,</span> <span class=\"n\">dataset_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;dataset&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Chicago&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Also, if you want to check what fields are in your datasets, set the argument <code class=\"docutils literal\"><span class=\"pre\">print_dataset</span></code> to <code class=\"docutils literal\"><span class=\"pre\">True</span></code>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">build_uctb_dataset</span><span class=\"p\">(</span><span class=\"n\">traffic_node</span><span class=\"o\">=</span><span class=\"n\">traffic_node</span><span class=\"p\">,</span> <span class=\"n\">time_fitness</span><span class=\"o\">=</span><span class=\"n\">time_fitness</span><span class=\"p\">,</span> \n                <span class=\"n\">node_station_info</span><span class=\"o\">=</span><span class=\"n\">node_station_info</span><span class=\"p\">,</span> <span class=\"n\">time_range</span><span class=\"o\">=</span><span class=\"n\">time_range</span><span class=\"p\">,</span> \n                <span class=\"n\">output_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;tmp_dir&#39;</span><span class=\"p\">,</span> <span class=\"n\">dataset_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;dataset&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Chicago&#39;</span><span class=\"p\">,</span> <span class=\"n\">print_dataset</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Output:</p>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span>dataset[TimeRange]:&lt;class &#39;list&#39;&gt;  (len=2)\ndataset[TimeFitness]:&lt;class &#39;int&#39;&gt;\ndataset[Node]:&lt;class &#39;dict&#39;&gt;{\n    dataset[Node][TrafficNode]:&lt;class &#39;numpy.ndarray&#39;&gt;  (shape=(37248, 532))\n    dataset[Node][StationInfo]:&lt;class &#39;list&#39;&gt;  (len=(532, 5))\n    dataset[Node][TrafficMonthlyInteraction]:&lt;class &#39;NoneType&#39;&gt;\n}\ndataset[Grid]:&lt;class &#39;dict&#39;&gt;{\n    dataset[Grid][TrafficGrid]:&lt;class &#39;NoneType&#39;&gt;\n    dataset[Grid][GridLatLng]:&lt;class &#39;NoneType&#39;&gt;\n}\ndataset[ExternalFeature]:&lt;class &#39;dict&#39;&gt;{\n    dataset[ExternalFeature][Weather]:&lt;class &#39;list&#39;&gt;  (len=0)\n}\ndataset[LenTimeSlots]:&lt;class &#39;int&#39;&gt;\n</pre></div>\n</div>\n<p>What's more, if you want to integrate additional information of the dataset, just specify the optional argument as bellow.</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\">Variable_name</th>\n<th align=\"left\">Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">traffic_monthly_interaction</td>\n<td align=\"left\">The interactive information among data collecting nodes.</td>\n</tr>\n<tr>\n<td align=\"left\">node_poi</td>\n<td align=\"left\">Point of interests conformed with node format</td>\n</tr>\n<tr>\n<td align=\"left\">grid_poi</td>\n<td align=\"left\">Point of interests conformed with grid format</td>\n</tr>\n<tr>\n<td align=\"left\">traffic_grid</td>\n<td align=\"left\">The spatio-temporal information in grid format.</td>\n</tr>\n<tr>\n<td align=\"left\">gird_lat_lng</td>\n<td align=\"left\">The basic information of each data collecting grid.</td>\n</tr>\n<tr>\n<td align=\"left\">external_feature_weather</td>\n<td align=\"left\">The weather information of each day.</td>\n</tr>\n</tbody>\n</table><p>for example, specify the argument <code class=\"docutils literal\"><span class=\"pre\">external_feature_weather</span></code> with numpy.array object.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">build_uctb_dataset</span><span class=\"p\">(</span><span class=\"n\">traffic_node</span><span class=\"o\">=</span><span class=\"n\">traffic_node</span><span class=\"p\">,</span> <span class=\"n\">time_fitness</span><span class=\"o\">=</span><span class=\"n\">time_fitness</span><span class=\"p\">,</span> \n                <span class=\"n\">node_station_info</span><span class=\"o\">=</span><span class=\"n\">node_station_info</span><span class=\"p\">,</span> <span class=\"n\">time_range</span><span class=\"o\">=</span><span class=\"n\">time_range</span><span class=\"p\">,</span> \n                <span class=\"n\">output_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;tmp_dir&#39;</span><span class=\"p\">,</span> <span class=\"n\">dataset_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;dataset&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Chicago&#39;</span><span class=\"p\">,</span> \n                <span class=\"n\">print_dataset</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">external_feature_weather</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"mi\">37248</span><span class=\"p\">,</span><span class=\"mi\">26</span><span class=\"p\">]))</span>\n</pre></div>\n</div>\n<p>The code above use zero matrix to specify the argument <code class=\"docutils literal\"><span class=\"pre\">external_feature_weather</span></code>. While in practical application scenario, you should substitute it with real feather matrix. The first dimension of the matrx is the number of time slots, and the second dimension corresponds to the dimension of weather features.</p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"predictive_tool.html\" class=\"btn btn-neutral float-right\" title=\"4. Predictive Tool\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"installation.html\" class=\"btn btn-neutral\" title=\"2. Installation\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/md_file/visualization_tool.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>5. Visualization-tool &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"6. API Reference\" href=\"../APIReference.html\"/>\n        <link rel=\"prev\" title=\"4. Predictive Tool\" href=\"predictive_tool.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">5. Visualization-tool</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#quick-start\">5.1. Quick Start</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#start-with-predefined-dataset\">5.1.1. Start with predefined dataset</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#start-with-prediction-and-ground-truth\">5.1.2. Start with prediction and ground truth</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#start-with-prediction-ground-truth-and-spatial-information\">5.1.3. Start with prediction, ground truth and spatial information</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#start-with-prediction-ground-truth-and-temporal-information\">5.1.4. Start with prediction, ground truth and temporal information</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#start-with-prediction-ground-truth-as-well-as-spatial-and-temporal-information\">5.1.5. Start with prediction, ground truth as well as spatial and temporal information</a></li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#contribute-to-our-project\">5.2. Contribute to our project.</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>5. Visualization-tool</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/visualization_tool.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"visualization-tool\">\n<h1>5. Visualization-tool<a class=\"headerlink\" href=\"#visualization-tool\" title=\"Permalink to this headline\">¶</a></h1>\n<p>We have developed a tool that integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis. Welcome to visit the <a class=\"reference external\" href=\"http://39.107.116.221/\">website</a> for a trial.</p>\n<div class=\"section\" id=\"quick-start\">\n<h2>5.1. Quick Start<a class=\"headerlink\" href=\"#quick-start\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"start-with-predefined-dataset\">\n<h3>5.1.1. Start with predefined dataset<a class=\"headerlink\" href=\"#start-with-predefined-dataset\" title=\"Permalink to this headline\">¶</a></h3>\n<p>You can click on the dropdown menu in the <code class=\"docutils literal\"><span class=\"pre\">predefined</span></code> module of the <code class=\"docutils literal\"><span class=\"pre\">Data</span> <span class=\"pre\">Loader</span></code>, select the dataset you need, and click <code class=\"docutils literal\"><span class=\"pre\">confirm</span></code> to obtain the required diagnosis and visualization.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_1.png\" alt=\"img\" style=\"zoom: 33%;\" /></div>\n<div class=\"section\" id=\"start-with-prediction-and-ground-truth\">\n<h3>5.1.2. Start with prediction and ground truth<a class=\"headerlink\" href=\"#start-with-prediction-and-ground-truth\" title=\"Permalink to this headline\">¶</a></h3>\n<p>You can upload specifically formatted TSV files for prediction and ground truth in the <code class=\"docutils literal\"><span class=\"pre\">upload</span></code> module of the Data Loader. Clicking <code class=\"docutils literal\"><span class=\"pre\">confirm</span></code> will enable you to obtain the corresponding diagnosis and visualization.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_2.png\" alt=\"img\" style=\"zoom: 33%;\" /></div>\n<div class=\"section\" id=\"start-with-prediction-ground-truth-and-spatial-information\">\n<h3>5.1.3. Start with prediction, ground truth and spatial information<a class=\"headerlink\" href=\"#start-with-prediction-ground-truth-and-spatial-information\" title=\"Permalink to this headline\">¶</a></h3>\n<p>You can upload specifically formatted TSV files for prediction, ground truth, and spatial information in the <code class=\"docutils literal\"><span class=\"pre\">upload</span></code> module of the <code class=\"docutils literal\"><span class=\"pre\">Data</span> <span class=\"pre\">Loader</span></code>. Clicking <code class=\"docutils literal\"><span class=\"pre\">confirm</span></code> will enable you to obtain the corresponding diagnosis and visualization.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_3.png\" alt=\"img\" style=\"zoom: 33%;\" /></div>\n<div class=\"section\" id=\"start-with-prediction-ground-truth-and-temporal-information\">\n<h3>5.1.4. Start with prediction, ground truth and temporal information<a class=\"headerlink\" href=\"#start-with-prediction-ground-truth-and-temporal-information\" title=\"Permalink to this headline\">¶</a></h3>\n<p>You can upload specifically formatted TSV files for prediction, and ground truth in the <code class=\"docutils literal\"><span class=\"pre\">upload</span></code> module of the 'Data Loader', along with the corresponding temporal information. Clicking <code class=\"docutils literal\"><span class=\"pre\">confirm</span></code> will enable you to obtain the corresponding diagnosis and visualization.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_4.png\" alt=\"img\" style=\"zoom: 33%;\" /></div>\n<div class=\"section\" id=\"start-with-prediction-ground-truth-as-well-as-spatial-and-temporal-information\">\n<h3>5.1.5. Start with prediction, ground truth as well as spatial and temporal information<a class=\"headerlink\" href=\"#start-with-prediction-ground-truth-as-well-as-spatial-and-temporal-information\" title=\"Permalink to this headline\">¶</a></h3>\n<p>You can upload specifically formatted TSV files for prediction, ground truth, and spatial information in the <code class=\"docutils literal\"><span class=\"pre\">upload</span></code> module of the <code class=\"docutils literal\"><span class=\"pre\">Data</span> <span class=\"pre\">Loader</span></code>, along with the corresponding temporal information. Clicking <code class=\"docutils literal\"><span class=\"pre\">confirm</span></code> will enable you to obtain the corresponding diagnosis and visualization.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_5.png\" alt=\".img\" style=\"zoom: 33%;\" /></div>\n</div>\n<div class=\"section\" id=\"contribute-to-our-project\">\n<h2>5.2. Contribute to our project.<a class=\"headerlink\" href=\"#contribute-to-our-project\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The visualization-tool offers two usage options, which are accessing through the <a class=\"reference external\" href=\"http://39.107.116.221/\">website</a>, or using the source code(for contribution).</p>\n<p><strong>Step 1: Requirements</strong></p>\n<div class=\"highlight-vue\"><div class=\"highlight\"><pre><span></span>node == 16.14.0\nnpm == 8.3.1\n</pre></div>\n</div>\n<p><strong>Step 2: Clone repository and install dependencies</strong></p>\n<div class=\"highlight-Vue\"><div class=\"highlight\"><pre><span></span>git clone https://github.com/uctb/visualization-tool-UCTB.git \ncd visualization-tool-UCTB \nnpm install\n</pre></div>\n</div>\n<p><strong>Step 3: Start</strong></p>\n<div class=\"highlight-Vue\"><div class=\"highlight\"><pre><span></span>npm run serve\n</pre></div>\n</div>\n<p>Then you will see the following prompt on the screen:</p>\n<div class=\"highlight-vue\"><div class=\"highlight\"><pre><span></span> App running at:\n  - Local:   http://localhost:xxxx/ \n  - Network: http://ip:xxxx/\n</pre></div>\n</div>\n<p>You can customize the visualization tool in the source code to achieve visual effects that better fit the objectives. To better assist you in achieving personalization of the visualization tool, we recommend following these steps to implement it.</p>\n<p><strong>Step 1: Create your own component</strong></p>\n<div class=\"highlight-vue\"><div class=\"highlight\"><pre><span></span>&lt;template&gt;\n&lt;div&gt;Your own HTML&lt;/div&gt;\n&lt;/template&gt;\n\n&lt;script&gt;\nexport default {\n\tname: &#39;your own component name&#39;,\n    data(){}\n}\n&lt;/script&gt;\n\n&lt;style scoped&gt;\n /*Your own CSS*/\n&lt;/style&gt;\n</pre></div>\n</div>\n<p><strong>Step 2: Importing component in App.vue</strong></p>\n<div class=\"highlight-vue\"><div class=\"highlight\"><pre><span></span>&lt;script&gt;\nimport YourOwnComponent from &quot;./components/YourOwnComponent.vue&quot;\nexport default {\n\tname: &#39;App&#39;,\n    components: {\n     YourOwnComponent\n    }\n}\n&lt;/script&gt;\n</pre></div>\n</div>\n<p>More instructions on the usage of Vue can be referred to on the <a class=\"reference external\" href=\"https://v2.vuejs.org/\">website</a>. <strong>If you have any interesting or novel ideas, we highly welcome your pull request:)</strong></p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"../APIReference.html\" class=\"btn btn-neutral float-right\" title=\"6. API Reference\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"predictive_tool.html\" class=\"btn btn-neutral\" title=\"4. Predictive Tool\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/modules.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>UCTB &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>UCTB</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/modules.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb\">\n<h1>UCTB<a class=\"headerlink\" href=\"#uctb\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.html\">UCTB package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.html#subpackages\">Subpackages</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.dataset.html\">6.1. UCTB.dataset package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.data_loader\">6.1.1. UCTB.dataset.data_loader module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.dataset\">6.1.2. UCTB.dataset.dataset module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.evaluation.html\">6.5. UCTB.evaluation package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.evaluation.html#module-UCTB.evaluation.metric\">6.5.1. UCTB.evaluation.metric module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.model.html\">6.4. UCTB.model package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ARIMA\">6.4.1. UCTB.model.ARIMA module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DCRNN\">6.4.2. UCTB.model.DCRNN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DeepST\">6.4.3. UCTB.model.DeepST module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GeoMAN\">6.4.4. UCTB.model.GeoMAN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.HM\">6.4.5. UCTB.model.HM module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STMeta\">6.4.6. UCTB.model.STMeta module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_MGCN\">6.4.7. UCTB.model.ST_MGCN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_ResNet\">6.4.8. UCTB.model.ST_ResNet module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.XGBoost\">6.4.9. UCTB.model.XGBoost module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.AGCRN\">6.4.10. UCTB.model.AGCRN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ASTGCN\">6.4.11. UCTB.model.ASTGCN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GMAN\">6.4.12. UCTB.model.GMAN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#uctb-model-graphwavenet-module\">6.4.13. UCTB.model.GraphWaveNet module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STGCN\">6.4.14. UCTB.model.STGCN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STSGCN\">6.4.15. UCTB.model.STSGCN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.model_unit.html\">6.3. UCTB.model_unit package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.BaseModel\">6.3.1. UCTB.model_unit.BaseModel module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.DCRNN_CELL\">6.3.2. UCTB.model_unit.DCRNN_CELL module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.GraphModelLayers\">6.3.3. UCTB.model_unit.GraphModelLayers module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.ST_RNN\">6.3.4. UCTB.model_unit.ST_RNN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.preprocess.html\">6.2. UCTB.preprocess package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#uctb-preprocess-graphgenerator-module\">6.2.1. UCTB.preprocess.GraphGenerator module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.preprocessor\">6.2.2. UCTB.preprocess.preprocessor module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.time_utils\">6.2.3. UCTB.preprocess.time_utils module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.train.html\">6.6. UCTB.train package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.EarlyStopping\">6.6.1. UCTB.train.EarlyStopping module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.MiniBatchTrain\">6.6.2. UCTB.train.MiniBatchTrain module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.utils.html\">6.7. UCTB.utils package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.utils.html#module-UCTB.utils.multi_threads\">6.7.1. UCTB.utils.multi_threads module</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.html#module-UCTB\">Module contents</a></li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/py-modindex.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Python Module Index &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n \n\n\n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>Python Module Index</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n\n   <h1>Python Module Index</h1>\n\n   <div class=\"modindex-jumpbox\">\n   <a href=\"#cap-u\"><strong>u</strong></a>\n   </div>\n\n   <table class=\"indextable modindextable\">\n     <tr class=\"pcap\"><td></td><td>&#160;</td><td></td></tr>\n     <tr class=\"cap\" id=\"cap-u\"><td></td><td>\n       <strong>u</strong></td><td></td></tr>\n     <tr>\n       <td><img src=\"_static/minus.png\" class=\"toggler\"\n              id=\"toggle-1\" style=\"display: none\" alt=\"-\" /></td>\n       <td>\n       <a href=\"UCTB.html#module-UCTB\"><code class=\"xref\">UCTB</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.dataset.html#module-UCTB.dataset.data_loader\"><code class=\"xref\">UCTB.dataset.data_loader</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.dataset.html#module-UCTB.dataset.dataset\"><code class=\"xref\">UCTB.dataset.dataset</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.evaluation.html#module-UCTB.evaluation.metric\"><code class=\"xref\">UCTB.evaluation.metric</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.AGCRN\"><code class=\"xref\">UCTB.model.AGCRN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.ARIMA\"><code class=\"xref\">UCTB.model.ARIMA</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.ASTGCN\"><code class=\"xref\">UCTB.model.ASTGCN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.DCRNN\"><code class=\"xref\">UCTB.model.DCRNN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.DeepST\"><code class=\"xref\">UCTB.model.DeepST</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.GeoMAN\"><code class=\"xref\">UCTB.model.GeoMAN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.GMAN\"><code class=\"xref\">UCTB.model.GMAN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.GraphWaveNet\"><code class=\"xref\">UCTB.model.GraphWaveNet</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.HM\"><code class=\"xref\">UCTB.model.HM</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.ST_MGCN\"><code class=\"xref\">UCTB.model.ST_MGCN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.ST_ResNet\"><code class=\"xref\">UCTB.model.ST_ResNet</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.STGCN\"><code class=\"xref\">UCTB.model.STGCN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.STMeta\"><code class=\"xref\">UCTB.model.STMeta</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.STSGCN\"><code class=\"xref\">UCTB.model.STSGCN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.XGBoost\"><code class=\"xref\">UCTB.model.XGBoost</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model_unit.html#module-UCTB.model_unit.BaseModel\"><code class=\"xref\">UCTB.model_unit.BaseModel</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model_unit.html#module-UCTB.model_unit.DCRNN_CELL\"><code class=\"xref\">UCTB.model_unit.DCRNN_CELL</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model_unit.html#module-UCTB.model_unit.GraphModelLayers\"><code class=\"xref\">UCTB.model_unit.GraphModelLayers</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model_unit.html#module-UCTB.model_unit.ST_RNN\"><code class=\"xref\">UCTB.model_unit.ST_RNN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.preprocess.html#module-UCTB.preprocess.GraphGenerator\"><code class=\"xref\">UCTB.preprocess.GraphGenerator</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.preprocess.html#module-UCTB.preprocess.preprocessor\"><code class=\"xref\">UCTB.preprocess.preprocessor</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.preprocess.html#module-UCTB.preprocess.time_utils\"><code class=\"xref\">UCTB.preprocess.time_utils</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.train.html#module-UCTB.train.EarlyStopping\"><code class=\"xref\">UCTB.train.EarlyStopping</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.train.html#module-UCTB.train.MiniBatchTrain\"><code class=\"xref\">UCTB.train.MiniBatchTrain</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.utils.html#module-UCTB.utils.multi_threads\"><code class=\"xref\">UCTB.utils.multi_threads</code></a></td><td>\n       <em></em></td></tr>\n   </table>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/search.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Search &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"#\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"#\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>Search</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <noscript>\n  <div id=\"fallback\" class=\"admonition warning\">\n    <p class=\"last\">\n      Please activate JavaScript to enable the search\n      functionality.\n    </p>\n  </div>\n  </noscript>\n\n  \n  <div id=\"search-results\">\n  \n  </div>\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n      <script type=\"text/javascript\" src=\"_static/searchtools.js\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n  \n  <script type=\"text/javascript\">\n    jQuery(function() { Search.loadIndex(\"searchindex.js\"); });\n  </script>\n  \n  <script type=\"text/javascript\" id=\"searchindexloader\"></script>\n   \n\n\n</body>\n</html>"
  },
  {
    "path": "docs/searchindex.js",
    "content": "Search.setIndex({docnames:[\"APIReference\",\"UCTB\",\"UCTB.dataset\",\"UCTB.evaluation\",\"UCTB.model\",\"UCTB.model_unit\",\"UCTB.preprocess\",\"UCTB.train\",\"UCTB.utils\",\"index\",\"md_file/all_results\",\"md_file/installation\",\"md_file/introduction\",\"md_file/predictive_tool\",\"md_file/src/image/README\",\"md_file/static/stable_test\",\"md_file/static/transfer_record\",\"md_file/uctb_group\",\"md_file/urban_dataset\",\"md_file/visualization_tool\",\"modules\",\"update_guide\"],envversion:53,filenames:[\"APIReference.rst\",\"UCTB.rst\",\"UCTB.dataset.rst\",\"UCTB.evaluation.rst\",\"UCTB.model.rst\",\"UCTB.model_unit.rst\",\"UCTB.preprocess.rst\",\"UCTB.train.rst\",\"UCTB.utils.rst\",\"index.rst\",\"md_file/all_results.md\",\"md_file/installation.md\",\"md_file/introduction.md\",\"md_file/predictive_tool.md\",\"md_file/src/image/README.md\",\"md_file/static/stable_test.md\",\"md_file/static/transfer_record.md\",\"md_file/uctb_group.md\",\"md_file/urban_dataset.md\",\"md_file/visualization_tool.md\",\"modules.rst\",\"update_guide.txt\"],objects:{\"\":{UCTB:[1,0,0,\"-\"]},\"UCTB.dataset\":{data_loader:[2,0,0,\"-\"],dataset:[2,0,0,\"-\"]},\"UCTB.dataset.data_loader\":{NodeTrafficLoader:[2,1,1,\"\"]},\"UCTB.dataset.data_loader.NodeTrafficLoader\":{daily_slots:[2,2,1,\"\"],dataset:[2,2,1,\"\"],external_dim:[2,2,1,\"\"],make_concat:[2,3,1,\"\"],station_number:[2,2,1,\"\"],train_closeness:[2,2,1,\"\"],train_y:[2,2,1,\"\"]},\"UCTB.dataset.dataset\":{DataSet:[2,1,1,\"\"]},\"UCTB.dataset.dataset.DataSet\":{MergeIndex:[2,2,1,\"\"],MergeWay:[2,2,1,\"\"],data:[2,2,1,\"\"],merge_data:[2,3,1,\"\"],node_monthly_interaction:[2,2,1,\"\"],node_station_info:[2,2,1,\"\"],node_traffic:[2,2,1,\"\"],time_fitness:[2,2,1,\"\"],time_range:[2,2,1,\"\"]},\"UCTB.evaluation\":{metric:[3,0,0,\"-\"]},\"UCTB.evaluation.metric\":{mae:[3,4,1,\"\"],mape:[3,4,1,\"\"],rmse:[3,4,1,\"\"],smape:[3,4,1,\"\"],trunc_mae:[3,4,1,\"\"],trunc_rmse:[3,4,1,\"\"],trunc_smape:[3,4,1,\"\"]},\"UCTB.model\":{AGCRN:[4,0,0,\"-\"],ARIMA:[4,0,0,\"-\"],ASTGCN:[4,0,0,\"-\"],DCRNN:[4,0,0,\"-\"],DeepST:[4,0,0,\"-\"],GMAN:[4,0,0,\"-\"],GeoMAN:[4,0,0,\"-\"],GraphWaveNet:[4,0,0,\"-\"],HM:[4,0,0,\"-\"],STGCN:[4,0,0,\"-\"],STMeta:[4,0,0,\"-\"],STSGCN:[4,0,0,\"-\"],ST_MGCN:[4,0,0,\"-\"],ST_ResNet:[4,0,0,\"-\"],XGBoost:[4,0,0,\"-\"]},\"UCTB.model.AGCRN\":{AGCRN:[4,1,1,\"\"]},\"UCTB.model.ARIMA\":{ARIMA:[4,1,1,\"\"]},\"UCTB.model.ARIMA.ARIMA\":{adf_test:[4,5,1,\"\"],get_order:[4,3,1,\"\"],predict:[4,3,1,\"\"]},\"UCTB.model.ASTGCN\":{ASTGCN_submodule:[4,1,1,\"\"],Spatial_Attention_layer:[4,1,1,\"\"],cheb_conv:[4,1,1,\"\"],cheb_conv_withSAt:[4,1,1,\"\"],cheb_polynomial:[4,4,1,\"\"],make_model:[4,4,1,\"\"]},\"UCTB.model.ASTGCN.ASTGCN_submodule\":{forward:[4,3,1,\"\"]},\"UCTB.model.ASTGCN.Spatial_Attention_layer\":{forward:[4,3,1,\"\"]},\"UCTB.model.ASTGCN.cheb_conv\":{forward:[4,3,1,\"\"]},\"UCTB.model.ASTGCN.cheb_conv_withSAt\":{forward:[4,3,1,\"\"]},\"UCTB.model.DCRNN\":{DCRNN:[4,1,1,\"\"]},\"UCTB.model.DCRNN.DCRNN\":{build:[4,3,1,\"\"]},\"UCTB.model.DeepST\":{DeepST:[4,1,1,\"\"]},\"UCTB.model.DeepST.DeepST\":{build:[4,3,1,\"\"]},\"UCTB.model.GMAN\":{GMAN:[4,4,1,\"\"],STEmbedding:[4,4,1,\"\"],alias_draw:[4,4,1,\"\"],alias_setup:[4,4,1,\"\"],gatedFusion:[4,4,1,\"\"],spatialAttention:[4,4,1,\"\"],temporalAttention:[4,4,1,\"\"],transformAttention:[4,4,1,\"\"]},\"UCTB.model.GeoMAN\":{GeoMAN:[4,1,1,\"\"],input_transform:[4,4,1,\"\"],split_timesteps:[4,4,1,\"\"]},\"UCTB.model.GeoMAN.GeoMAN\":{build:[4,3,1,\"\"]},\"UCTB.model.GraphWaveNet\":{gwnet:[4,1,1,\"\"]},\"UCTB.model.HM\":{HM:[4,1,1,\"\"]},\"UCTB.model.HM.HM\":{predict:[4,3,1,\"\"]},\"UCTB.model.STGCN\":{build_model:[4,4,1,\"\"],cheb_poly_approx:[4,4,1,\"\"],fully_con_layer:[4,4,1,\"\"],gconv:[4,4,1,\"\"],gen_batch:[4,4,1,\"\"],layer_norm:[4,4,1,\"\"],output_layer:[4,4,1,\"\"],spatio_conv_layer:[4,4,1,\"\"],st_conv_block:[4,4,1,\"\"],temporal_conv_layer:[4,4,1,\"\"],variable_summaries:[4,4,1,\"\"]},\"UCTB.model.STMeta\":{STMeta:[4,1,1,\"\"]},\"UCTB.model.STMeta.STMeta\":{build:[4,3,1,\"\"]},\"UCTB.model.STSGCN\":{construct_adj:[4,4,1,\"\"],gcn_operation:[4,4,1,\"\"],get_adjacency_matrix:[4,4,1,\"\"],output_layer:[4,4,1,\"\"],position_embedding:[4,4,1,\"\"],sthgcn_layer_individual:[4,4,1,\"\"],sthgcn_layer_sharing:[4,4,1,\"\"],stsgcl:[4,4,1,\"\"],stsgcm:[4,4,1,\"\"],stsgcn:[4,4,1,\"\"]},\"UCTB.model.ST_MGCN\":{ST_MGCN:[4,1,1,\"\"]},\"UCTB.model.ST_MGCN.ST_MGCN\":{build:[4,3,1,\"\"]},\"UCTB.model.ST_ResNet\":{ST_ResNet:[4,1,1,\"\"]},\"UCTB.model.ST_ResNet.ST_ResNet\":{build:[4,3,1,\"\"]},\"UCTB.model.XGBoost\":{XGBoost:[4,1,1,\"\"]},\"UCTB.model.XGBoost.XGBoost\":{fit:[4,3,1,\"\"],predict:[4,3,1,\"\"]},\"UCTB.model_unit\":{BaseModel:[5,0,0,\"-\"],DCRNN_CELL:[5,0,0,\"-\"],GraphModelLayers:[5,0,0,\"-\"],ST_RNN:[5,0,0,\"-\"]},\"UCTB.model_unit.BaseModel\":{BaseModel:[5,1,1,\"\"]},\"UCTB.model_unit.BaseModel.BaseModel\":{build:[5,3,1,\"\"],close:[5,3,1,\"\"],fit:[5,3,1,\"\"],load:[5,3,1,\"\"],load_event_scalar:[5,3,1,\"\"],predict:[5,3,1,\"\"],save:[5,3,1,\"\"]},\"UCTB.model_unit.DCRNN_CELL\":{DCGRUCell:[5,1,1,\"\"]},\"UCTB.model_unit.DCRNN_CELL.DCGRUCell\":{call:[5,3,1,\"\"],compute_output_shape:[5,3,1,\"\"],output_size:[5,2,1,\"\"],state_size:[5,2,1,\"\"]},\"UCTB.model_unit.GraphModelLayers\":{GAL:[5,1,1,\"\"],GCL:[5,1,1,\"\"]},\"UCTB.model_unit.GraphModelLayers.GAL\":{add_ga_layer_matrix:[5,5,1,\"\"],add_residual_ga_layer:[5,5,1,\"\"],attention_merge_weight:[5,5,1,\"\"]},\"UCTB.model_unit.GraphModelLayers.GCL\":{add_gc_layer:[5,5,1,\"\"],add_multi_gc_layers:[5,5,1,\"\"]},\"UCTB.model_unit.ST_RNN\":{GCLSTMCell:[5,1,1,\"\"]},\"UCTB.preprocess\":{GraphGenerator:[6,0,0,\"-\"],preprocessor:[6,0,0,\"-\"],time_utils:[6,0,0,\"-\"]},\"UCTB.preprocess.GraphGenerator\":{GraphGenerator:[6,1,1,\"\"],scaled_Laplacian_ASTGCN:[6,4,1,\"\"],scaled_laplacian_STGCN:[6,4,1,\"\"]},\"UCTB.preprocess.GraphGenerator.GraphGenerator\":{AM:[6,2,1,\"\"],LM:[6,2,1,\"\"],adjacent_to_laplacian:[6,5,1,\"\"],correlation_adjacent:[6,5,1,\"\"],distance_adjacent:[6,3,1,\"\"],haversine:[6,5,1,\"\"],interaction_adjacent:[6,5,1,\"\"]},\"UCTB.preprocess.preprocessor\":{MaxMinNormalizer:[6,1,1,\"\"],Normalizer:[6,1,1,\"\"],ST_MoveSample:[6,1,1,\"\"],SplitData:[6,1,1,\"\"],WhiteNormalizer:[6,1,1,\"\"],ZscoreNormalizer:[6,1,1,\"\"],chooseNormalizer:[6,4,1,\"\"]},\"UCTB.preprocess.preprocessor.MaxMinNormalizer\":{inverse_transform:[6,3,1,\"\"],transform:[6,3,1,\"\"]},\"UCTB.preprocess.preprocessor.ST_MoveSample\":{move_sample:[6,3,1,\"\"]},\"UCTB.preprocess.preprocessor.SplitData\":{split_data:[6,5,1,\"\"],split_feed_dict:[6,5,1,\"\"]},\"UCTB.preprocess.preprocessor.WhiteNormalizer\":{inverse_transform:[6,3,1,\"\"],transform:[6,3,1,\"\"]},\"UCTB.preprocess.preprocessor.ZscoreNormalizer\":{inverse_transform:[6,3,1,\"\"],transform:[6,3,1,\"\"]},\"UCTB.preprocess.time_utils\":{is_valid_date:[6,4,1,\"\"],is_work_day_america:[6,4,1,\"\"],is_work_day_china:[6,4,1,\"\"]},\"UCTB.train\":{EarlyStopping:[7,0,0,\"-\"],MiniBatchTrain:[7,0,0,\"-\"]},\"UCTB.train.EarlyStopping\":{EarlyStopping:[7,1,1,\"\"],EarlyStoppingTTest:[7,1,1,\"\"]},\"UCTB.train.EarlyStopping.EarlyStopping\":{__best:[7,2,1,\"\"],__p:[7,2,1,\"\"],__patience:[7,2,1,\"\"],__record_list:[7,2,1,\"\"],stop:[7,3,1,\"\"]},\"UCTB.train.EarlyStopping.EarlyStoppingTTest\":{__best:[7,2,1,\"\"],__p_value_threshold:[7,2,1,\"\"],__record_list:[7,2,1,\"\"],__test_length:[7,2,1,\"\"],stop:[7,3,1,\"\"]},\"UCTB.train.MiniBatchTrain\":{MiniBatchFeedDict:[7,1,1,\"\"],MiniBatchTrain:[7,1,1,\"\"],MiniBatchTrainMultiData:[7,1,1,\"\"]},\"UCTB.train.MiniBatchTrain.MiniBatchFeedDict\":{get_batch:[7,3,1,\"\"],restart:[7,3,1,\"\"],shuffle:[7,5,1,\"\"]},\"UCTB.train.MiniBatchTrain.MiniBatchTrain\":{get_batch:[7,3,1,\"\"],restart:[7,3,1,\"\"],shuffle:[7,5,1,\"\"]},\"UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData\":{get_batch:[7,3,1,\"\"],restart:[7,3,1,\"\"],shuffle:[7,5,1,\"\"]},\"UCTB.utils\":{multi_threads:[8,0,0,\"-\"]},\"UCTB.utils.multi_threads\":{multiple_process:[8,4,1,\"\"]}},objnames:{\"0\":[\"py\",\"module\",\"Python module\"],\"1\":[\"py\",\"class\",\"Python class\"],\"2\":[\"py\",\"attribute\",\"Python attribute\"],\"3\":[\"py\",\"method\",\"Python method\"],\"4\":[\"py\",\"function\",\"Python function\"],\"5\":[\"py\",\"staticmethod\",\"Python static method\"]},objtypes:{\"0\":\"py:module\",\"1\":\"py:class\",\"2\":\"py:attribute\",\"3\":\"py:method\",\"4\":\"py:function\",\"5\":\"py:staticmethod\"},terms:{\"10h\":15,\"10m\":[12,18],\"18m\":[12,18],\"21m\":[12,18],\"7500m\":15,\"89m\":[12,18],\"\\u4e00\\u5171\\u6709428\\u79cdpoi\":16,\"\\u4e09\\u4e2a\\u57ce\\u5e02\\u7684poi\\u6570\\u91cf\\u4e0echeck\":16,\"\\u4e4b\\u95f4\":16,\"\\u5206\\u522b\\u4e3a\\u5de5\\u4f5c\\u65e5\":16,\"\\u5230\":16,\"\\u534a\\u5f84\\u4e3a50km\\u7684poi\\u6570\\u91cf\":16,\"\\u5373\\u6bcf\\u4e2a\\u7ad9\\u70b9\\u6709428\\u7ef4\\u7279\\u5f81\":16,\"\\u5373\\u6bcf\\u4e2a\\u7ad9\\u70b9\\u7684\\u7279\\u5f81\\u7ef4\\u5ea6\\u4e3a48\":16,\"\\u53f3\\u4fa7\\u4e3a\":16,\"\\u5404\\u4e2a\\u81ea\\u884c\\u8f66\\u7ad9\\u70b9\\u9644\\u8fd11km\\u7684checkin\\u603b\\u6570\\u91cf\":16,\"\\u5747\\u503c\":15,\"\\u57ce\\u5e02\":16,\"\\u591a\\u6b21\\u5b9e\\u9a8c\\u7ed3\\u679c\":15,\"\\u5b9e\\u9a8c\\u7f16\\u53f7\":15,\"\\u5de5\\u4f5c\\u65e511707\":16,\"\\u5de5\\u4f5c\\u65e52549\":16,\"\\u5de5\\u4f5c\\u65e56049\":16,\"\\u5de6\\u4fa7\\u4e3a\":16,\"\\u5e73\\u5747\\u8017\\u65f6\":15,\"\\u6309\\u7167\\u5de5\\u4f5c\\u65e5\\u548c\\u8282\\u5047\\u65e5\\u5206\\u5f00\":16,\"\\u65e5\\u5747check\":16,\"\\u65f6\\u95f4\\u8303\\u56f4\":16,\"\\u6682\\u65f6\\u53ea\\u8dd1\\u4e864\\u6b21\":15,\"\\u6700\\u7ec8\\u7ed3\\u679c\":15,\"\\u6807\\u51c6\\u5dee\":15,\"\\u6a21\\u578b\\u7248\\u672c\\u542b\\u4e49\":15,\"\\u6bcf\\u4e2a\\u7ad9\\u70b9\\u7edf\\u8ba1\\u9644\\u8fd11km\\u51fa\\u73b0\\u7684poi\\u7c7b\\u578b\":16,\"\\u6bcf\\u6b21\\u5b9e\\u9a8c\\u8017\\u65f6\":15,\"\\u6bcf\\u6b21\\u5b9e\\u9a8c\\u8017\\u65f6\\u7ea6\":15,\"\\u7c97\\u7565\\u8ba1\\u7b97\\u6240\\u6709\\u7ad9\\u70b9\\u9644\\u8fd11km\\u7684checkin\\u6570\\u91cf\\u603b\\u548c\":16,\"\\u7ea2\\u8272\\u4ee3\\u8868\\u5dee\\u4e8efinetun\":16,\"\\u7eff\\u8272\\u7684\\u70b9\\u8868\\u793atransfer\\u6548\\u679c\\u597d\\u4e8efinetun\":16,\"\\u8282\\u5047\\u65e511358\":16,\"\\u8282\\u5047\\u65e52692\":16,\"\\u8282\\u5047\\u65e55450\":16,\"\\u8282\\u5047\\u65e5\\u768424\\u5c0f\\u65f6checkin\":16,\"\\u8ba1\\u7b97\":16,\"\\u8ba1\\u7b97\\u57ce\\u5e02\\u4e2d\\u5fc3\\u4e3a\\u539f\\u70b9\":16,\"\\u8bad\\u7ec3\\u6837\\u672c\\u6570\\u91cf\":16,\"abstract\":6,\"byte\":18,\"case\":13,\"class\":[2,4,5,6,7,13,18],\"default\":[2,4,5,6,7,19],\"export\":19,\"final\":[5,8,13,18],\"float\":[2,3,4,5,6,7,13],\"function\":[2,4,5,6,8,12,13,18,21],\"import\":[11,13,18,19],\"in\\u6570\\u91cf\":16,\"int\":[2,4,5,6,7,8,13,18],\"long\":13,\"new\":[2,4,7,10,13,18],\"null\":7,\"poi\\u6570\\u91cf\":16,\"public\":[12,18],\"return\":[2,4,5,6,7,8,13],\"rmse\\u503c\":15,\"short\":13,\"static\":[4,5,6,7],\"super\":13,\"true\":[2,4,5,6,7,13,15,18],\"try\":13,\"var\":4,\"while\":18,And:[13,18],Bus:[9,12],For:[7,13,18],Its:[2,7],Los:18,The:[2,4,5,6,7,8,10,12,13,18,19,21],Then:[11,13,18,19,21],There:[7,18],These:[4,10,13],Used:[2,6],Using:[11,13],With:18,__best:7,__init__:[5,11,13],__p:7,__p_value_threshold:7,__patienc:7,__record_list:7,__test_length:7,_build:21,_graph:13,_input:13,_op:13,_output:13,aaai:[4,12],abc:6,abl:[13,18],abnorm:18,about:[9,12,13,18],abov:[13,18],absolut:3,academi:17,accept:[8,13],access:[13,18,19],accord:[4,6,7,13,18],account:13,accus:13,achiev:19,acquir:13,act_func:4,activ:[4,5,11,17,18],adajac:6,adam:4,adamoptim:13,adapt:[4,12,13],add:[4,5,13,21],add_ga_layer_matrix:5,add_gc_lay:5,add_multi_gc_lay:5,add_residual_ga_lay:5,addaptadj:4,added:5,adding:5,addit:18,adf_test:4,adj:4,adjac:[4,6,13,18],adjacent_matrix:[6,13],adjacent_to_laplacian:[6,13],adjust:[2,4],adopt:[13,18],adptiv:13,advanc:9,affect:18,after:[4,5,11,13,21],against:13,agcrn:[0,1,10,12,20],agcrncel:4,aggreg:[5,18],alajali:13,algorithm:[4,13],alia:4,alias_draw:4,alias_setup:4,align:13,all:[2,4,6,8,13,15,18],allow:[12,19],almost:5,along:19,alpha:5,alreadi:[11,18],also:[2,5,6,12,13,18],although:18,alwai:13,america:6,among:[8,13,18],anaconda:9,analysi:[4,13,18],analyt:13,angel:18,ani:[13,19],anoth:18,anyth:6,api:[4,9,13,18],apidoc:21,app:19,appear:13,append:[5,7,13],applehelp:21,appli:18,applic:[10,12,18],appreci:12,approxim:[4,5],apr:16,april:[13,17],aptinit:4,arbitrari:2,architectur:[11,13],archiv:18,area:[13,18],arg:[5,10,13],argu:4,argument:[13,18],arima:[0,1,10,12,20],arma:4,around:18,arrai:[6,13,18],arrang:2,array_lik:4,articl:4,arxiv:10,as_default:13,assist:[17,18,19],associ:17,assum:[13,18],astgcn:[0,1,12,20],astgcn_submodul:4,astyp:13,attach:4,attenion:13,attent:[4,5,12,13],attention_merge_weight:5,attet:13,attribut:[2,4,18],aug:17,augment:4,author:18,auto:5,auto_load_model:5,autom:17,automat:5,autoregress:[4,13],avail:18,averag:[2,4,7,13],avoid:11,awesom:12,axi:[4,13],bachelor:17,back:[11,12,13,18],backend:11,bai:[10,12,13,18],base:[2,4,5,6,7,11,12,13],basemodel:[0,1,4,13,20],basi:[13,18],basic:[2,13,18],basiclstmcel:13,batch:[4,5,7,13],batch_siz:[3,4,5,7,10,13],batchsiz:15,becaus:[13,18],been:18,befor:[5,13],begin:[13,18],beij:10,being:[13,18],bellow:18,below:[11,18],benchmark:9,best:[7,10],better:[7,13,19],between:[2,6,18],bia:5,bidirect:13,big:[17,21],bigger:4,bike:[4,9,12,13],bike_chicago:10,bike_dc:10,bike_nyc:10,binar:6,block:[4,13],blog:4,bn_decai:4,bold:10,bool:[2,4,5,6,7],boost:[4,13],both:[4,5,12,13],box:12,build:[2,4,5,6,9,11,12,21],build_instal:11,build_model:4,build_uctb_dataset:18,built:[4,18],bus:18,c_0:4,c_in:4,c_out:4,cach:5,cache_volum:5,calcul:[4,6,13],call:[5,6,7,13],callabl:4,can:[2,4,5,6,7,10,11,12,13,18,19,21],candid:18,cannot:11,capitalbikeshar:18,captur:[4,13],castleliang:[4,13],catalog:18,caus:18,cdw:10,cell:5,censu:[12,18],certain:[2,6],cgrnn:12,chai:17,chang:[2,4,6,7,11,13],channel:[4,5],characterist:6,chargest:10,chargestation_beij:10,chart:[12,19],cheb_conv:4,cheb_conv_withsat:4,cheb_k:4,cheb_poly_approx:4,cheb_polynomi:4,chebyshev:[4,5],check:[7,9,13,18],chen:[13,17],chengdu:10,chenliyue2019:17,chi:18,chicago:[10,12,18],china:[6,17],chines:17,chongq:10,choos:[4,6,13,18],choosenorm:6,chose:13,circl:6,citi:[2,6,10,12,13,15,17,18],citibikenyc:18,cityofnewyork:18,citywid:[4,13],cl_decay_step:4,clarifi:18,classic:13,click:19,clip:4,clone:[11,19],close:[2,4,5,6,10,12],closeness_featur:[4,13],closeness_len:[2,4,6,13],closenss:6,cmap:13,cmd:21,cnn:12,code:[4,5,8,10,11,13,18,19,21],code_vers:[4,5,13],codevers:15,coeffici:6,collect:18,com:[4,11,17,18,19],combin:[8,11,12,13,19],come:18,command:11,commonli:13,commonmark:21,commun:[12,18],compar:13,compat:[11,18],complet:13,complex:18,compon:[4,13,19],compos:[4,6,13],comprehens:18,comput:[3,4,6,11,12,17,18],compute_output_shap:5,con:10,concat:4,concaten:[2,6,13],conclus:10,concret:13,conda:11,conduct:[10,13,18],confid:17,config:[4,13],confirm:19,conflict:11,conform:18,connect:[4,12],consecut:[2,4,6,13],consid:[13,18],considerd:4,consist:[2,4,6,7,13],constant:13,constantli:18,construct:[2,4,12,13],construct_adj:4,constructor:13,contain:[2,4,13,18],content:20,continu:13,contrib:13,contribut:[9,18],contribute_data:2,contributor:9,conv_filt:[4,10],converg:13,convert:[6,18],convolut:[4,5,13],coordin:2,copi:21,copyright:11,correl:[4,6,10,13,15],correlation_adjac:6,correspond:[4,5,6,13,18,19,21],cosin:16,could:[11,18],count:[12,13,18],counti:18,creat:[2,11,13,19],credit:11,crop:4,crowd:[4,12,13],cse:17,csr_matrix:4,css:19,csv:4,cu100:11,cuda:11,cudatoolkit:11,cug:17,cui:17,cuizhenyu18:17,cummin:13,current:[4,5,7,9,12,18],custom:[4,13,19],customizeddemo:13,cut:8,dai:[2,4,6,13,18],daili:[4,13],daily_slot:[2,6],data:[2,3,4,5,6,7,8,10,12,13,17,18,19],data_dir:[2,13],data_list:8,data_load:[0,1,4,6,13,18,20],data_path:18,data_rang:[2,10,13],datafram:4,dataload:[2,18],datarang:15,dataset:[0,1,4,5,6,9,12,15,20],dataset_nam:18,datast:9,datatyp:2,date:6,date_str:6,datetim:6,davidham3:[4,13],dayofweek:4,dcg:10,dcgrucel:5,dchai:17,dcrnn:[0,1,10,12,20],dcrnn_cell:[0,1,20],debug:4,dec:18,decemb:18,decid:7,decim:6,decis:13,decod:[4,13],deep:[4,5,11,13,17],deepst:[0,1,12,20],def:13,default_graph:4,defin:[4,13],definit:6,degre:[4,6,17],demamd:18,demand:[4,12,13,18],demonstr:13,denorm:[6,13],dens:[4,13,18],denseunit:15,depart:17,depend:[4,13,19],depth:[4,10],describ:[4,13,18],descript:18,deseri:18,design:[11,13,18],desir:13,detail:[4,9,12,13,18],detector:18,determin:5,develop:19,devhelp:21,deviat:6,devic:[4,15],diagnosi:[12,19],dickei:4,dict:[2,4,5,6,7,13,18],dictionari:[6,7,18],didi:[8,10],didi_chengdu:10,didi_xian:10,diffcult:18,differ:[4,6,8,13],differenc:4,diffus:[4,13],digit:18,dilat:4,dilation_channel:4,dim:[4,18],dimens:[2,4,6,7,18],direct:16,directli:[2,7],directori:[2,4,5,13,18],dis_matrix:13,disabl:5,discard:18,discret:[4,18],disk:[5,18],dist:11,distacn:6,distanc:[2,4,6,10,13,15],distance_adjac:6,distance_df_filenam:4,distribut:[4,8,18],distribute_list:8,div:19,divid:[4,6,7,13],divis:13,divvybik:18,dnn:[4,13],doc:11,docstr:21,document:12,doe:[4,18],domain:[4,13],download:[11,18],downstream:18,downtown:18,draw:4,driven:[4,10,13],drop:4,drop_out:4,dropdown:19,dropoff:18,dropout:4,dropout_r:4,dtype:[5,13],due:[11,18],dump:18,duplic:18,dure:[2,6,18],dynam:[4,13],dynamic_batch:4,dynamic_rnn:13,each:[4,6,7,8,13,18],earli:[4,5,7,13,18],earlier:2,early_stop_length:5,early_stop_method:5,early_stop_pati:5,earlystop:[0,1,5,20],earlystoppingttest:7,earth:6,easi:[4,13],edg:4,edu:[4,17],effect:[13,19],effici:4,effort:13,either:13,element:[6,18],els:[5,13],email:17,embed:[2,4],embed_dim:4,embedding_s:4,empir:13,emploi:13,empti:2,enabl:19,encod:[4,13],encompass:18,encourag:11,end:[2,4,13,18],end_channel:4,engin:17,enjoi:11,enough:7,enrich:18,env:11,environ:11,epoch:[5,13,15],epsilon:4,equal:[3,4,5,6,7,18],equip:11,error:[3,11,12,13,19],eslength:15,especi:18,estim:18,estimat:10,etc:[12,13,18],euclidean:13,eval_metr:4,evalu:[0,1,4,9,20],evaluate_loss_nam:5,everi:[2,4,6,13],exact:[2,4,6],exampl:[13,18],exce:7,except:[5,13],execut:13,exist:[5,11,13],expand_dim:13,expect:7,experi:[10,11,13],explain:[5,13],explan:15,explicitli:13,exploit:13,explor:13,extend:13,extern:[2,4,13,18],externai_dim:4,external_dim:[2,4,13],external_featur:[4,13],external_feature_weath:18,externalfeatur:18,extra:13,extract:[2,6,10,13,18],f_in:4,f_out:4,fact:[18,21],factor:[4,10,13],faculti:18,fail:[11,13],failur:11,fals:[2,4,5,6,7,13,15],fan:13,fang:17,fangjiangyi2001:17,far:[4,13],feather:18,featur:[2,4,5,6,7,9,18],feb:17,februari:[13,18],fee:18,feed_dict:[6,7],feng:13,few:18,field:18,figur:13,file:[2,4,5,8,10,11,18,19,21],filenam:[4,5],fill:[13,18],filter:4,filter_list:4,final_st:13,find:[11,13],fine:18,finetun:16,finish:[13,18],first:[7,11,13,18,21],firstli:13,fit:[4,5,13,18,19],five:10,fix:[13,18],flag:5,flexibl:12,float32:[5,13],flog:5,flow:[4,9,12,13],folder:11,follow:[10,11,12,13,18,19],forecast:[4,13],forecast_step:[4,13],forget:13,form:[18,21],format:[2,6,12,13,19],former:[2,4,6,13],forward:4,found:[5,10,13,18],four:18,foxmail:17,frame:4,framework:[4,9,13],fratur:4,freeli:18,frequenc:18,from:[2,4,5,6,7,8,11,17,19],fujian:17,full:18,fuller:4,fulli:4,fully_con_lay:4,further:[2,18],fuse:[4,13],fusion:[4,13],futur:[4,13,18],gal:[4,5,10],galhead:15,galunit:15,gate:[4,5,12],gatedfus:4,gbrt:10,gc_output:5,gc_rate:4,gcl:[5,10],gcl_k:4,gcl_l:4,gclstm:4,gclstm_layer:4,gclstmcell:5,gcn:[4,5],gcn_bool:4,gcn_k:[4,5],gcn_l:5,gcn_layer:4,gcn_oper:4,gconv:4,gen_batch:4,gener:[4,6,7,13,21],geng:[4,13],geo:[4,13],geograph:6,geoman:[0,1,12,20],geoscienc:17,ger:13,get:[7,9,11,21],get_a_cel:13,get_adjacency_matrix:4,get_batch:7,get_ord:4,gird_lat_lng:18,git:[11,19],github:[4,11,13,18,19],give:[4,11],given:[4,6],gll:15,global:[4,13],global_featur:4,global_step:5,glu:4,gmail:17,gman:[0,1,10,12,20],gnn:12,goal:13,good:13,got:17,gov:18,gpu:[4,5,9],gpu_devic:[4,5,13],gradient:[4,13],graduat:17,grain:18,granular:[2,9,10,12,13],graph:[2,4,5,6,10,12],graph_merg:4,graph_merge_gal_num_head:4,graph_merge_gal_unit:4,graph_nam:13,graph_obj:13,graphbuild:13,graphgener:[0,1,13,20],graphmodellay:[0,1,20],graphwavenet:[0,1,12,20],great:6,greater:6,grid:[4,12,18],grid_poi:18,gridlatlng:18,gridtrafficload:18,ground:4,groundtruth:13,group:[9,15],gru:4,guo:13,guoshnbjtu:[4,13],gw6p:18,gwnet:4,hail:[4,13],hand:18,handl:[5,13,18],hang:17,hardwar:11,harvard:4,has:[2,18],have:[2,4,6,7,11,18,19],haversin:[6,13],head:[4,5],heapq:13,heatmap:13,height:4,help:[6,11,13,18],here:[11,13,18,21],heurist:13,hidden:[4,5],hidden_dim:4,high:[9,17,18],highest:[4,5],highest_protocol:18,highli:[11,18,19],highlight:10,highwai:18,hip:4,his:17,hisrori:4,histor:[4,18],histori:[2,4,6],hm_obj:13,hmm:12,hmmlearn:13,hoc:13,hoel:13,hold:5,holidai:[6,18],homepag:[11,12,13,17],hong:17,horovod:11,hourli:18,how:[2,4,9,11,12,13],html:[11,19,21],htmlhelp:21,http:[4,11,18,19],huazhong:17,huber:4,hyperparamet:[4,13],hypothesi:7,hyymmmint:17,iclr:12,id_filenam:4,idea:19,ident:7,ieee:10,ignor:4,ijcai:12,ild:6,illustr:13,imag:14,implement:[4,5,9,12,13,19],improv:11,in_arg:6,in_channel:4,in_dim:4,includ:[4,6,11,12,13,18],incorpor:[4,13],ind:13,independ:7,index:[2,4,8],indic:2,individu:4,info:18,inform:[4,5,8,11,13,18],inherit:[5,6,13],init:[4,5,13],init_var:[4,5,13],initi:[4,5,6,13,18],input:[2,4,5,6,7,8,12,13],input_dim:[4,5,13],input_length:4,input_shap:5,input_step:[4,13],input_transform:4,inspect:13,instal:[9,19,21],instanc:[4,13,18],instead:13,instruct:19,insuffici:18,integ:[2,4,8],integr:[12,13,18,19],interact:[2,6,10,12,15,18,19],interaction_adjac:6,interaction_matrix:6,interatct:6,interest:[18,19],interfac:[13,18],intern:7,intersect:13,interv:[7,13,18],introduc:18,introduct:9,inverse_transform:[6,13],is_train:[2,4],is_valid_d:6,is_work_day_america:[2,6],is_work_day_china:6,iter:[4,13,18],its:[2,4,6,11,13],jan:17,januari:18,jiang:13,jiangyi:17,jin:17,jinxu:17,job:8,job_i:8,jsmath:21,jul:17,juli:[13,17],junbo:4,just:[13,18,21],keep:5,keep_prob:4,kei:[6,7,9,13],kera:5,kernal_s:10,kernel:4,kernel_initi:5,kernel_s:[4,10],kind:4,knowledg:[10,12,19],known:11,kong:17,kwarg:[2,4,5,6,13],l_tild:4,lab:17,label:4,laboratori:17,lack:18,lag:4,land:[4,13],lapalac:6,laplac:6,laplace_matrix:13,laplacian:[4,5,6,13],laplacian_matrix:5,larg:18,larger:6,largest:18,last:[4,7,13],lat1:6,lat2:6,lat:18,lat_lng_list:[6,13],late:[4,13],later:2,latest:[2,6,18],latitud:[2,6,18],layer:[4,5,13],layer_norm:4,lead:11,leaky_relu:5,learn:[4,11,13,17],learner:4,least:13,legend:13,leibai:[4,13],len:[4,13,18],len_input:4,len_seq:4,length:[2,4,5,6,7,13,18],lentimeslot:18,less:[2,4,13,18],let:[13,18],level:[4,13],ley:17,leyewang:17,liang:[4,13],librari:[4,11,18,21],licens:11,like:[5,11],likelihood:4,limit:7,lin:13,line:[6,10,12,13,15],linear:13,link:[6,12,18],list:[2,4,5,6,7,8,18],liu:[13,17],liyaguang:[4,13],liyu:17,lng:18,load:[5,9],load_event_scalar:5,loader:[2,13,18,19],local:[4,12,13,18,19,21],local_featur:4,localhost:19,locat:[6,13,18,21],locker:8,log:5,lon1:6,lon2:6,longbiao:17,longbiaochen:17,longitud:[2,6],longtitud:18,look:[11,13,18],loss:[4,5,13],lot:13,low:11,lower:13,lstm:[4,5,10,12,13],lstm_layer:4,lstm_unit:4,lstmc:10,lstmcell:5,lstmunit:15,lucktroi:[4,13],luzern:[12,18],machin:[4,11,13],mae:3,mai:[2,4,11,13,17,18],mail:17,main:[2,18],major:[4,13,17],make:[4,18],make_concat:[2,13],make_model:4,mani:[2,4,5,6,13],map:[4,10,18],mape:[3,15],march:17,mark:[10,13],markdown:21,mask:4,mask_init_valu:4,master:[11,17],matplotlib:[13,18],matric:[4,6],matrix:[4,5,6,13,18],matrx:18,max:[2,4,5,13],max_ar:4,max_d:4,max_depth:[4,13],max_diffusion_step:[4,5],max_epoch:[5,13],max_lag:4,max_ma:4,max_to_keep:[4,5,13],maximum:[4,6],maxminnorm:6,mean:[3,4,6],mechan:[4,13],meet:18,melbourn:[12,18],member:13,memori:[5,13,18],mention:18,menu:19,merg:[4,13,18],merge_data:2,merge_gal_unit:5,mergeindex:[2,10,13,18],mergewai:[2,13,18],meteorolog:[4,13],meter:6,method:[2,4,5,6,7,13],metr:[10,13,18],metr_la:10,metric:[0,1,4,13,20],metro:[9,12,13,15],metro_chongq:10,metro_shanghai:[10,13],metropolitan:18,mgcn:[4,5,10,12],middl:4,might:18,million:18,min:[12,13,18],min_max_denorm:13,min_max_norm:13,mini:5,minibatchfeeddict:7,minibatchtrain:[0,1,20],minibatchtrainmultidata:7,minim:13,minimum:[6,13],minut:[2,12,18],miss:18,mode:4,model:[0,1,2,5,7,9,10,12,19,20],model_dir:[4,5,13],model_obj:13,model_r:4,model_unit:[0,1,4,9,13,20],modifi:[10,13],modul:[0,12,13,18,19,20],module_typ:4,month:[6,18],month_num:2,monthli:2,more:[4,5,8,10,11,12,13,18,19],move:[4,13],move_sampl:6,mta:18,much:18,multi:[4,5,10,13,18],multi_thread:[0,1,20],multipl:4,multiple_process:8,multirnncel:13,must:[4,5,13,21],mxnet:[4,11],my_dataset:18,my_lstm:13,my_model:13,mymodel:13,n_decoder_hidden_unit:4,n_encoder_hidden_unit:4,n_estim:[4,13],n_frame:4,n_hi:4,n_iter:13,n_jo:8,n_job:8,n_node:4,n_rout:4,n_stacked_lay:4,naiv:[4,5],name:[2,4,5,12,13,18,19],nb_block:4,nb_chev_filt:4,nb_predict_step:4,nb_time_filt:4,ndarrai:[2,3,4,5,6,7,18],nearest:13,necessari:[13,18],need:[2,4,5,6,11,13,18,19],neighbor:6,neighborhood:12,neighbour_adjac:13,nerual:13,network:[4,5,12,13,18,19],neural:[2,4,5,6,13],neurip:12,new_valu:7,newaxi:13,newer:11,newest:7,next:[13,21],nine:13,nlargest:13,nni:10,nnzhan:[4,13],node:[2,4,5,6,12,13,18,19],node_monthly_interact:2,node_num:[2,4],node_poi:18,node_satation_info:18,node_station_info:[2,13,18],node_traff:[2,18],nodetrafficload:[2,6,13,18],non:[4,13],none:[2,3,4,5,13],nonetyp:18,norm:4,normal:[2,4,6,13,15],notat:15,note:[2,4,13],noth:5,nov:17,novel:[13,19],novemb:13,now:[2,4,6,11,13,17,18],npm:19,num:[4,18],num_block:4,num_chev_filt:4,num_compon:13,num_conv_filt:4,num_dense_unit:4,num_diffusion_matrix:4,num_featu:5,num_featur:5,num_for_predict:4,num_graph:[4,5,13],num_head:5,num_hidden_unit:4,num_lay:[4,13],num_nod:[4,5,6,13],num_of_featur:4,num_of_filt:4,num_of_timestep:4,num_of_vertic:4,num_proj:5,num_residual_unit:[4,10],num_rnn_lay:4,num_rnn_unit:4,num_stat:13,num_step:4,num_time_filt:4,num_unit:[5,13],number:[2,4,5,6,7,8,10,11,18],numpi:[6,13,18],nvidia:11,nyc:[4,10,12,13,18],nyu:18,obei:18,obj:10,object:[2,4,5,6,7,13,18,19],observ:4,obtain:[6,13,18,19],occur:11,octob:13,offer:[18,19],often:13,ojs:4,onc:7,one:[2,4,5,6,7,8,10,13,18],onli:[4,7,11,13,18],op_nam:5,open:[12,18],opendata:18,oper:[4,13,18],operation1_nam:5,operation2_nam:5,ops:5,optim:[4,5,13],optimizer_nam:4,option:[2,4,18,19],order:[4,5,7,13],org:[4,11],orgin:6,origin:[2,18],other:[2,5,9,13],otherwis:[4,5,6,7,18],othewis:2,our:[5,9,13,18],out_channel:4,out_dim:4,outcom:4,output:[4,5,8,11,13,18],output_activ:4,output_dim:[4,13],output_dir:18,output_lay:4,output_nam:[5,13],output_s:5,output_step:[4,13],output_tensor1_nam:5,output_tensor1_valu:5,output_tensor_name1:5,output_tensor_name2:5,outputs_dict:5,over:18,overal:16,overview:9,overwrit:5,own:[2,5,6,9,19],p_test:13,p_value_threshold:7,packag:[0,9,11,12,13,18,20],page:[11,18],pair:[2,6,7,13],pan:13,panda:13,paper:[4,10,13],param:[2,3,4,5],paramet:[2,3,4,5,6,7,8,10,13],part:[4,8,13],partit:8,partition_func:8,pass:[4,13],past:[9,13,21],path:[2,4,18],patienc:[7,15],pattern:13,pearson:6,pedestrian:[9,12],pedestrian_melbourn:18,peke:17,pem:[10,18],pems_bai:10,percentag:3,perform:[5,13],period:[2,4,6,12],period_featur:[4,13],period_len:[2,4,6,10,13],person:19,perspect:13,phase:13,php:4,pickl:[2,18],pickup:18,piec:[2,4,6,13],pip:[11,21],pkl:18,pkl_file_nam:18,pku:17,place:18,placehold:[4,13],pleas:11,plot:[13,18],pls:8,plt:[13,18],poi:18,point:[4,6,13,18],polynomi:[4,5],popular:13,portal:18,posit:[2,6],position_embed:4,possibl:18,postgradu:17,potenti:11,practic:18,pred:13,pred_step:4,predict:[2,3,4,5,6,9,18],predict_length:4,prediction_test:13,prefix:4,prepar:18,preprocess:[0,1,9,13,18,20],preprocessor:[0,1,13,20],presenc:4,present:4,preserv:18,preset:13,previou:4,principl:18,print:[5,13,18],print_dataset:18,prior:12,privaci:18,prob:4,probabl:[13,18],problem:[11,13],procedur:18,process:[2,4,6,8,13,18],professor:17,project:[9,11,18],prompt:19,proper:[6,18],properti:[4,13],proport:2,propos:18,protocol:18,provid:[5,12,13,18,19],proxim:[10,12],public_dataset:18,pull:19,put:[13,18],pyindex:11,pyplot:[13,18],python:[5,10,11,13,18],pytorch:[4,11,13],qthelp:21,question:11,quick:9,quickstart:[4,11,13],random:13,rang:[2,12,13,18],raster:18,rate:4,ratio:[2,4,6,16],ratio_list:6,ration:5,raw:[6,13,18],read:18,readm:11,real:18,real_denorm:13,realiz:13,recent:13,recognit:13,recommend:[11,18,19],recommonmark:21,record:[2,4,6,7,10,13,18],recurr:[4,5,13],red:13,redefin:13,reduc:[8,13],reduce_func:8,reduce_mean:13,ref:4,refer:[4,8,9,11,13,19],reg:[4,13],region:13,regular:5,regularli:18,rel:2,relat:[13,21],releas:[5,12,18],relu:4,remov:[2,3,13],replac:3,repo:12,report:11,repositori:[4,12,13,18,19],repres:6,represent:5,request:19,requir:[13,19],research:18,reserv:4,reshap:13,residu:[4,5,13],residual_channel:4,residual_unit:10,resnet:[4,10,12],resourc:14,respect:[10,13,18],restart:7,restor:[6,18],result:[2,4,5,9,11,13,16,18],retain:18,retrun:4,return_output:5,reus:5,revers:13,rho:4,ride:[4,12,13,18],ridership:18,rideshar:12,rmse:[3,4,13,15],rnn:[4,5,12,13],rnn_cell:13,rnn_cell_impl:5,rnncell:5,road:[12,18],root:[3,4,13],rout:[4,18],rtcat:21,rtd:21,run:[10,13,18,19,21],runtim:11,s_rmse:3,sai:18,same:[2,3,4,5,6,12,13,18],sampl:[4,7,13],sarima:12,save:[4,5,18],save_model:5,save_model_nam:5,saver:5,scalar:5,scalar_nam:5,scale:[4,6,18],scaled_laplacian_astgcn:6,scaled_laplacian_stgcn:6,scenario:18,schedul:13,schmidhub:13,scienc:17,scipi:4,scope:[4,19],score:4,scratch:7,screen:19,script:[13,18,19],sea:4,seaborn:13,season:[4,13],seasonal_ord:[4,13],second:[2,18,21],secondari:21,section:[12,13,18,21],see:[2,4,7,12,13,19],seen:18,select:[2,6,13,18,19],self:[2,6,13],send:8,sens:17,sensor:[4,12,13,18],sensori:[4,13],sep:17,sept:16,seq_len:4,sequenc:[4,5,18],sequence_length:[5,6,7,13],seri:[4,13],serial:[4,18],serializinghtml:21,serv:19,session:[5,7],set:[2,4,5,7,10,13,18],setup:11,seven:[2,4,6],sever:[7,11],sgd:4,shahabi:13,shall:2,shanghai:[10,13,15],shanghaiv1:15,shape:[2,3,4,5,6,13,18],share:[4,12,18],share_queu:8,shawnwang:[4,13],shortest:13,should:[2,4,5,6,7,8,13,18],show:[10,12,13,18,19],shown:[13,18],shuffl:[4,5,7],shuffle_data:5,side:7,sigmoid:4,sigspati:12,silent:4,similar:[2,4,12,13,16],simpl:[4,13],simpli:[4,13],simplifi:18,sinc:[4,13],singl:[2,4],site:18,situat:[11,13,18],six:18,size:[4,5,7,18],skip:[4,11],skip_channel:4,slot:[2,4,6,13,18],small:[7,18],smaller:[3,6,7],smape:3,smart:17,snowbridg:17,sns:13,softmax:5,softwar:17,solut:11,some:[11,12,18,21],song:13,sort:2,sourc:[11,12,19],span:[7,10,18],spars:[4,18],spatial:[4,5,10,12,13,18],spatial_attent:4,spatial_attention_lay:4,spatial_emb:4,spatialattent:4,spatio:[4,13,18],spatio_conv_lay:4,spatiotempor:[4,12,13,19],special:18,specif:[11,12,18,19],specifi:[2,4,5,6,10,13,18],spectral:4,speed:[9,12,13],sphinx:21,sphinxcontrib:21,split:[2,4,6,13],split_data:6,split_feed_dict:6,split_timestep:4,splitdata:[6,13],splite:13,sqrt:13,squar:[3,13],squarederror:[4,13],st0:15,st_conv:4,st_conv_block:4,st_map:13,st_method:4,st_mgcn:[0,1,12,20],st_movesampl:6,st_resnet:[0,1,5,10,12,20],st_rnn:[0,1,20],st_sim1_0:15,st_sim_0:15,stack:4,stacked_cel:13,stacked_output:13,stackoverflow:11,standard:[4,6],start:[2,9,11,18],state:[5,12,13,18],state_is_tupl:13,state_s:5,statement:13,station:[2,4,10,13,18],station_index:13,station_numb:[2,13],stationari:18,stationinfo:[2,18],statist:[13,18],statsmodel:13,statt:4,statu:18,ste:4,ste_p:4,ste_q:4,stembed:4,step:[2,4,5,6,11,13,19],stgcn:[0,1,10,12,20],sthgcn_layer_individu:4,sthgcn_layer_shar:4,still:18,stitch:13,stmeta:[0,1,5,10,12,15,20],stmeta_obj:[10,13],stmeta_obj_topk:13,stmeta_v0:10,stmeta_v1:[10,13],stmeta_v2:10,stmeta_v3:10,stop:[5,7,13,18],store:[2,4,5,6],str:[2,4,5,6],stream:[2,18],stride:[4,13],string:[2,4,5,6],strnn:4,strongli:18,structur:[4,12,13],stsgcl:4,stsgcm:4,stsgcn:[0,1,12,20],sttp:18,stu:17,student:17,style:19,subclass:13,subpackag:20,subscript:5,subset:6,substitut:18,suburb:18,subwai:18,success:9,successfulli:[11,21],sum:[2,13,18],summar:18,summari:4,supplementari:2,support:[4,5,9,12],sym:4,symmetr:3,synchron:[4,13],system:[10,13,18],t_0:4,t_in:4,t_out:4,tabl:[18,21],tail:7,take:[7,13,18],tanh:[4,5],target:[3,4,6,7,13],target_len:4,target_length:[2,6,13],target_nod:13,target_nodz:13,target_st:13,task:[4,8,12,13,18],task_func:8,taxi:[9,12],tcn:12,tech:[4,13],techniqu:[5,12],technolog:17,temperatur:4,templat:[18,19],tempor:[2,4,5,6,10,12,18],temporal_conv_lay:4,temporal_emb:4,temporal_merg:4,temporal_merge_gal_num_head:4,temporal_merge_gal_unit:4,temporalattent:4,temporam:4,tengfei:17,tensor:[4,5,13],tensorboard:[4,5],tensorflow:[4,5,11,13],term:13,test:[2,4,5,7],test_clos:[2,13],test_ef:13,test_i:[2,13],test_period:[2,13],test_predict:13,test_prediction_collector:13,test_ratio:[2,13],test_rms:13,test_sequence_len:13,test_trend:[2,13],test_x:13,text:21,tf66366:17,than:[2,3,4,6,7,13,18],thank:11,thei:[7,13],them:[6,11,13,18],theme:21,theoret:13,therefor:13,theta:4,thi:[4,5,6,7,10,11,12,13,18,21],thing:21,those:7,thread:8,three:[4,8,13,18],threshold:[3,6,7,13,15],threshold_correl:[6,13],threshold_dist:[6,13],threshold_interact:[6,13],threshold_neighbour:13,through:[13,18,19],thu:[5,11,18],till:17,time:[2,4,6,7,10,12,13,18],time_fit:[2,6,18],time_index:13,time_rang:[2,18],time_sequ:[4,13],time_seri:4,time_slot_num:[2,4],time_step:4,time_strid:4,time_util:[0,1,20],timefit:[2,18],timeofdai:4,timerang:[2,18],timespan:18,timestep:[4,13],titl:[13,21],tkde:12,tlc:18,tmeta:10,tmp_dir:18,togeth:6,toi:13,too:2,tool:9,toolbox:[11,12],toolkit:10,top:[10,13],topk:13,topkgraph:13,torch:[4,11],torch_stabl:11,torchvis:11,total:[4,13,18],total_sens:4,tract:[12,18],trafalgar2001:17,traffic:[2,4,12,13,18],traffic_data:[6,13],traffic_data_index:13,traffic_grid:18,traffic_monthly_interact:18,traffic_nod:18,trafficgrid:18,trafficmonthlyinteract:[2,18],trafficnod:[2,18],train:[0,1,2,4,5,9,15,20],train_clos:[2,13],train_data:13,train_data_length:[2,10,13],train_ef:13,train_i:[2,13],train_loss:13,train_op:[5,13],train_period:[2,13],train_sequence_len:13,train_test_ratio:13,train_time_slot_num:2,train_trend:[2,13],train_x:13,trainabl:[4,5],trainable_var:13,trainbl:13,traindai:15,transfer:[6,16],transform:[4,6,13,18],transformattent:4,transport:[12,18],transpos:13,tree:[4,13,18],trend:[2,4,6,12],trend_featur:[4,13],trend_len:[2,4,6,10,13],trial:[12,19],trick:13,trigger:7,trip:18,trunc_ma:3,trunc_rms:3,trunc_smap:3,truncat:3,truth:4,tsv:19,turn:6,tutori:[5,9,11,12],two:[2,4,6,7,10,13,18,19],type:[2,3,4,5,6,7,11,12,13],type_:4,uca:17,uctb:[0,11,12,19,21],ultim:[13,18],under:13,undergradu:17,uniform:4,uniqu:[4,13],unit:[4,5,13],univari:4,univers:17,unknown:18,unseen:11,unzip:18,updat:[18,21],upgrad:11,upload:[12,19],urban:[9,13],usag:[13,19],use:[2,4,5,10,11,12,18,21],use_bia:5,use_curriculum_learn:4,use_gc_for_ru:5,use_mask:4,used:[2,4,5,6,8,13,18],useful:13,user:[6,11],uses:18,using:[4,5,6,11,18,19],ust:17,utd19:18,util:[0,1,4,9,20],v_name:4,val_loss:[5,13],valid:[4,5,6,13],validate_ratio:[5,13],valu:[4,6,7,13,15,18],variabl:[4,7,13,18],variable_nam:18,variable_summari:4,variou:[12,18],vector:6,vehicl:[12,18],vehicular:13,verbos:[4,5],veritasyin:[4,13],version:[4,5,9,13,18,21],vertic:4,via:[9,13],view:4,vis:11,vision:17,visit:[12,19],visual:[4,9,10,13,18],vmax:13,vmin:13,vstack:13,vue:19,wai:[6,13,18],walk:13,wan:13,wang:[13,17],want:[18,21],wavenet:[4,10,13],weather:18,websit:[12,18,19],week:[2,4,6],weekli:4,weight:[4,5,6],welcom:[12,18,19],well:[11,12,13],wen:13,wenji:17,were:18,what:[11,18],when:[2,4,5,7,11,13,18,21],where:[4,6,8,18],whether:[4,5,7,18],which:[2,4,5,6,8,11,13,18,19],whitenorm:6,whl:11,whole:[5,13],whose:[2,7,13],wide:[13,18],width:4,william:13,wind:4,window:[11,18],with_lm:13,with_tp:[2,4,13],without:[6,13],wjycc:17,won:[6,18],work:[4,11,18],workday_pars:2,worldwid:18,wors:7,worth:13,wrapper:13,www:[11,18],x_denorm:13,x_normal:13,x_train:6,xavier:4,xgboost:[0,1,10,12,20],xiamen:17,xian:10,xie:17,xiuhuai:17,xlabel:13,xmu:17,xplore:10,xueqiao:17,xxx:11,xxxx:19,y_pred:13,y_truth:13,yaguang:4,yaml:11,yang:[13,17],yao:13,yayao:17,year:18,yin:13,ylabel:13,yml:[10,13],york:[10,13,18],yoshal:[4,13],you:[5,6,11,12,13,18,19,21],your:[2,5,6,9,11,12,19],yourowncompon:19,yuxuan:4,yyyi:[2,18],zero:[13,18],zhang:[4,13],zheng:13,zhengchuanpan:4,zhenyu:17,zhihu:4,zhou:13,zhu:[13,17],zhuanlan:4,zhuhang:17,zip:18,zone:18,zscorenorm:6},titles:[\"6. API Reference\",\"UCTB package\",\"6.1. UCTB.dataset package\",\"6.5. UCTB.evaluation package\",\"6.4. UCTB.model package\",\"6.3. UCTB.model_unit package\",\"6.2. UCTB.preprocess package\",\"6.6. UCTB.train package\",\"6.7. UCTB.utils package\",\"Welcome to UCTB\\u2019s documentation!\",\"7. Benchmark\",\"2. Installation\",\"1. Introduction\",\"4. Predictive Tool\",\"&lt;no title&gt;\",\"Stable Test Records\",\"Check-In\\u4e0ePOI\\u6570\\u636e\\u5904\\u7406\\u65b9\\u6cd5\",\"8. About us (UCTB Group)\",\"3. Urban Datasets\",\"5. Visualization-tool\",\"UCTB\",\"&lt;no title&gt;\"],titleterms:{\"\\u4f7f\\u7528check\":16,\"\\u4f7f\\u7528poi\\u4fe1\\u606f\\u8fdb\\u884c\\u76f8\\u4f3c\\u7ad9\\u70b9\\u5339\\u914d\":16,\"\\u5206\\u6790transfer\\u6548\\u679c\\u5728\\u57ce\\u5e02\\u4e2d\\u7684\\u5206\\u5e03\":16,\"\\u6570\\u636e\\u8be6\\u60c5\":16,\"\\u7279\\u5f81\\u76f8\\u4f3c\\u5ea6\\u65b9\\u6cd5\":16,\"\\u7279\\u5f81\\u8ba1\\u7b97\\u65b9\\u6cd5\":16,\"in\\u4e0epoi\\u6570\\u636e\\u5904\\u7406\\u65b9\\u6cd5\":16,\"in\\u6570\\u636e\\u8fdb\\u884c\\u76f8\\u4f3c\\u7ad9\\u70b9\\u7684\\u5339\\u914d\":16,\"poi\\u7279\\u5f81\\u8ba1\\u7b97\\u65b9\\u6cd5\":16,Bus:18,Use:[13,18],about:17,advanc:13,agcrn:[4,13],anaconda:11,api:0,arima:[4,13],astgcn:[4,13],basemodel:5,beij:15,benchmark:10,bike:[10,18],build:[13,15,18],chargest:15,check:[11,16],chengdu:15,chicago:16,citi:16,close:13,content:1,contribut:19,contributor:17,current:13,data_load:2,dataset:[2,10,13,18,19],datast:12,dcrnn:[4,13],dcrnn_cell:5,deepst:[4,13],definit:13,detail:10,didi:15,document:9,earlystop:7,electr:10,evalu:[3,13],featur:13,flow:18,format:18,framework:11,from:[13,18],full:13,geoman:[4,13],get:18,gman:[4,13],gpu:11,granular:18,graph:[13,15],graphgener:6,graphmodellay:5,graphwavenet:[4,13],ground:19,group:17,hidden:13,high:11,histor:13,hmm:13,how:18,implement:10,inform:19,instal:11,introduct:12,kei:17,kind:13,knowledg:13,load:[13,18],make:13,markov:13,mean:13,metric:3,metro:[10,18],mgcn:13,minibatchtrain:7,minut:10,model:[4,13,15],model_unit:5,modul:[1,2,3,4,5,6,7,8],multi_thread:8,multipl:13,nyc:16,other:18,our:19,overview:18,own:[13,18],packag:[1,2,3,4,5,6,7,8],paramet:15,passeng:10,past:17,pedestrian:18,period:13,predefin:19,predict:[10,12,13,19],preprocess:6,preprocessor:6,project:19,quick:[13,19],record:15,refer:0,regress:13,resnet:13,result:10,ride:10,search:10,share:10,singl:13,space:10,spatial:19,speed:[10,18],st_mgcn:4,st_resnet:4,st_rnn:5,stabl:15,start:[13,19],stgcn:[4,13],stmeta:[4,13],stsgcn:[4,13],subpackag:1,success:11,support:[11,13],target:16,task:10,taxi:18,tempor:[13,19],test:[13,15],time_util:6,tool:[12,13,19],traffic:10,train:[7,13],trend:13,truth:19,tutori:13,uctb:[1,2,3,4,5,6,7,8,9,13,17,18,20],urban:[12,18],urban_dataset:13,use:13,using:13,util:8,vehicl:10,version:11,via:11,visual:[12,19],welcom:9,well:19,xgboost:[4,13],xian:15,your:[13,18]}})"
  },
  {
    "path": "docs/sphinx/APIReference.rst",
    "content": "API Reference\n====================\n\n.. toctree::\n\n    UCTB.dataset.rst\n\n    UCTB.preprocess.rst\n\n    UCTB.model_unit.rst\n\n    UCTB.model.rst\n\n    UCTB.evaluation.rst\n\n    UCTB.train.rst\n\n    UCTB.utils.rst"
  },
  {
    "path": "docs/sphinx/Makefile",
    "content": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the environment for the first two.\nSPHINXOPTS    ?=\nSPHINXBUILD   ?= sphinx-build\nSOURCEDIR     = .\nBUILDDIR      = _build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n"
  },
  {
    "path": "docs/sphinx/UCTB.dataset.rst",
    "content": "UCTB.dataset package\n====================\n\nUCTB.dataset.data\\_loader module\n--------------------------------\n\n.. automodule:: UCTB.dataset.data_loader\n   :members:\n   :show-inheritance:\n\nUCTB.dataset.dataset module\n---------------------------\n\n.. automodule:: UCTB.dataset.dataset\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/UCTB.evaluation.rst",
    "content": "UCTB.evaluation package\n=======================\n\n\nUCTB.evaluation.metric module\n-----------------------------\n\n.. automodule:: UCTB.evaluation.metric\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/UCTB.model.rst",
    "content": "UCTB.model package\n==================\n\nUCTB.model.ARIMA module\n-----------------------\n\n.. automodule:: UCTB.model.ARIMA\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.DCRNN module\n-----------------------\n\n.. automodule:: UCTB.model.DCRNN\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.DeepST module\n------------------------\n\n.. automodule:: UCTB.model.DeepST\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.GeoMAN module\n------------------------\n\n.. automodule:: UCTB.model.GeoMAN\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.HM module\n--------------------\n\n.. automodule:: UCTB.model.HM\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.STMeta module\n------------------------\n\n.. automodule:: UCTB.model.STMeta\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.ST\\_MGCN module\n--------------------------\n\n.. automodule:: UCTB.model.ST_MGCN\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.ST\\_ResNet module\n----------------------------\n\n.. automodule:: UCTB.model.ST_ResNet\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.XGBoost module\n-------------------------\n\n.. automodule:: UCTB.model.XGBoost\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.AGCRN module\n-------------------------\n\n.. automodule:: UCTB.model.AGCRN\n   :members:\n   :show-inheritance:\n\nUCTB.model.ASTGCN module\n-------------------------\n\n.. automodule:: UCTB.model.ASTGCN\n   :members:\n   :show-inheritance:\n\nUCTB.model.GMAN module\n-------------------------\n\n.. automodule:: UCTB.model.GMAN\n   :members:\n   :show-inheritance:\n\nUCTB.model.GraphWaveNet module\n-------------------------\n\n.. automodule:: UCTB.model.GraphWaveNet\n   :members:\n   :show-inheritance:\n\nUCTB.model.STGCN module\n-------------------------\n\n.. automodule:: UCTB.model.STGCN\n   :members:\n   :show-inheritance:\n\nUCTB.model.STSGCN module\n-------------------------\n\n.. automodule:: UCTB.model.STSGCN\n   :members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/UCTB.model_unit.rst",
    "content": "UCTB.model\\_unit package\n========================\n\n\nUCTB.model\\_unit.BaseModel module\n---------------------------------\n\n.. automodule:: UCTB.model_unit.BaseModel\n   :members:\n   :show-inheritance:\n\nUCTB.model\\_unit.DCRNN\\_CELL module\n-----------------------------------\n\n.. automodule:: UCTB.model_unit.DCRNN_CELL\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model\\_unit.GraphModelLayers module\n----------------------------------------\n\n.. automodule:: UCTB.model_unit.GraphModelLayers\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model\\_unit.ST\\_RNN module\n-------------------------------\n\n.. automodule:: UCTB.model_unit.ST_RNN\n   :members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/UCTB.preprocess.rst",
    "content": "UCTB.preprocess package\n=======================\n\n\nUCTB.preprocess.GraphGenerator module\n-----------------------------------\n\n.. automodule:: UCTB.preprocess.GraphGenerator\n   :members:\n   :show-inheritance:\n\nUCTB.preprocess.preprocessor module\n-----------------------------------\n\n.. automodule:: UCTB.preprocess.preprocessor\n   :members:\n   :show-inheritance:\n\nUCTB.preprocess.time\\_utils module\n----------------------------------\n\n.. automodule:: UCTB.preprocess.time_utils\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/UCTB.rst",
    "content": "UCTB package\n============\n\nSubpackages\n-----------\n\n.. toctree::\n\n   UCTB.dataset\n   UCTB.evaluation\n   UCTB.model\n   UCTB.model_unit\n   UCTB.preprocess\n   UCTB.train\n   UCTB.utils\n\nModule contents\n---------------\n\n.. automodule:: UCTB\n   :members:\n   :undoc-members:\n   :show-inheritance:\n"
  },
  {
    "path": "docs/sphinx/UCTB.train.rst",
    "content": "UCTB.train package\n==================\n\nUCTB.train.EarlyStopping module\n-------------------------------\n\n.. automodule:: UCTB.train.EarlyStopping\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.train.MiniBatchTrain module\n--------------------------------\n\n.. automodule:: UCTB.train.MiniBatchTrain\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/UCTB.utils.rst",
    "content": "UCTB.utils package\n==================\n\nUCTB.utils.multi\\_threads module\n--------------------------------\n\n.. automodule:: UCTB.utils.multi_threads\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n\n\n"
  },
  {
    "path": "docs/sphinx/_build/.buildinfo",
    "content": "# Sphinx build info version 1\n# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.\nconfig: 3f9422ea59d6af9d5ca292dc751485b5\ntags: 645f666f9bcd5a90fca523b33c5a78b7\n"
  },
  {
    "path": "docs/sphinx/_build/.nojekyll",
    "content": ""
  },
  {
    "path": "docs/sphinx/_build/APIReference.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6. API Reference &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"next\" title=\"6.1. UCTB.dataset package\" href=\"UCTB.dataset.html\"/>\n        <link rel=\"prev\" title=\"5. Visualization-tool\" href=\"md_file/visualization_tool.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">6. API Reference</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html\">6.1. UCTB.dataset package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html\">6.2. UCTB.preprocess package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html\">6.3. UCTB.model_unit package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html\">6.4. UCTB.model package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.evaluation.html\">6.5. UCTB.evaluation package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html\">6.6. UCTB.train package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.utils.html\">6.7. UCTB.utils package</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>6. API Reference</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/APIReference.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"api-reference\">\n<h1>6. API Reference<a class=\"headerlink\" href=\"#api-reference\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.dataset.html\">6.1. UCTB.dataset package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.data_loader\">6.1.1. UCTB.dataset.data_loader module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.dataset\">6.1.2. UCTB.dataset.dataset module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.preprocess.html\">6.2. UCTB.preprocess package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#uctb-preprocess-graphgenerator-module\">6.2.1. UCTB.preprocess.GraphGenerator module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.preprocessor\">6.2.2. UCTB.preprocess.preprocessor module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.time_utils\">6.2.3. UCTB.preprocess.time_utils module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.model_unit.html\">6.3. UCTB.model_unit package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.BaseModel\">6.3.1. UCTB.model_unit.BaseModel module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.DCRNN_CELL\">6.3.2. UCTB.model_unit.DCRNN_CELL module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.GraphModelLayers\">6.3.3. UCTB.model_unit.GraphModelLayers module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.ST_RNN\">6.3.4. UCTB.model_unit.ST_RNN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.model.html\">6.4. UCTB.model package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ARIMA\">6.4.1. UCTB.model.ARIMA module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DCRNN\">6.4.2. UCTB.model.DCRNN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DeepST\">6.4.3. UCTB.model.DeepST module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GeoMAN\">6.4.4. UCTB.model.GeoMAN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.HM\">6.4.5. UCTB.model.HM module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STMeta\">6.4.6. UCTB.model.STMeta module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_MGCN\">6.4.7. UCTB.model.ST_MGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_ResNet\">6.4.8. UCTB.model.ST_ResNet module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.XGBoost\">6.4.9. UCTB.model.XGBoost module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.AGCRN\">6.4.10. UCTB.model.AGCRN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ASTGCN\">6.4.11. UCTB.model.ASTGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GMAN\">6.4.12. UCTB.model.GMAN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#uctb-model-graphwavenet-module\">6.4.13. UCTB.model.GraphWaveNet module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STGCN\">6.4.14. UCTB.model.STGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STSGCN\">6.4.15. UCTB.model.STSGCN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.evaluation.html\">6.5. UCTB.evaluation package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.evaluation.html#module-UCTB.evaluation.metric\">6.5.1. UCTB.evaluation.metric module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.train.html\">6.6. UCTB.train package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.EarlyStopping\">6.6.1. UCTB.train.EarlyStopping module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.MiniBatchTrain\">6.6.2. UCTB.train.MiniBatchTrain module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.utils.html\">6.7. UCTB.utils package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.utils.html#module-UCTB.utils.multi_threads\">6.7.1. UCTB.utils.multi_threads module</a></li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.dataset.html\" class=\"btn btn-neutral float-right\" title=\"6.1. UCTB.dataset package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"md_file/visualization_tool.html\" class=\"btn btn-neutral\" title=\"5. Visualization-tool\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/UCTB.dataset.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.1. UCTB.dataset package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.2. UCTB.preprocess package\" href=\"UCTB.preprocess.html\"/>\n        <link rel=\"prev\" title=\"6. API Reference\" href=\"APIReference.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.1. UCTB.dataset package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.dataset.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-dataset-package\">\n<h1>6.1. UCTB.dataset package<a class=\"headerlink\" href=\"#uctb-dataset-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.dataset.data_loader\">\n<span id=\"uctb-dataset-data-loader-module\"></span><h2>6.1.1. UCTB.dataset.data_loader module<a class=\"headerlink\" href=\"#module-UCTB.dataset.data_loader\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.dataset.data_loader.</code><code class=\"descname\">NodeTrafficLoader</code><span class=\"sig-paren\">(</span><em>dataset</em>, <em>city=None</em>, <em>data_range='all'</em>, <em>train_data_length='all'</em>, <em>test_ratio=0.1</em>, <em>closeness_len=6</em>, <em>period_len=7</em>, <em>trend_len=4</em>, <em>target_length=1</em>, <em>normalize=True</em>, <em>workday_parser=&lt;function is_work_day_america&gt;</em>, <em>with_tpe=False</em>, <em>data_dir=None</em>, <em>MergeIndex=1</em>, <em>MergeWay='sum'</em>, <em>remove=True</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>The data loader that extracts and processes data from a <code class=\"xref py py-obj docutils literal\"><span class=\"pre\">DataSet</span></code> object.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>dataset</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – A string containing path of the dataset pickle file or a string of name of the dataset.</li>\n<li><strong>city</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><code class=\"xref py py-obj docutils literal\"><span class=\"pre\">str</span></code></a> or <code class=\"docutils literal\"><span class=\"pre\">None</span></code>) – <code class=\"docutils literal\"><span class=\"pre\">None</span></code> if dataset is file path, or a string of name of the city.\nDefault: <code class=\"docutils literal\"><span class=\"pre\">None</span></code></li>\n<li><strong>data_range</strong> – The range of data extracted from <code class=\"docutils literal\"><span class=\"pre\">self.dataset</span></code> to be further used. If set to <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code>, all data in\n<code class=\"docutils literal\"><span class=\"pre\">self.dataset</span></code> will be used. If set to a float between 0.0 and 1.0, the relative former proportion of data in\n<code class=\"docutils literal\"><span class=\"pre\">self.dataset</span></code> will be used. If set to a list of two integers <code class=\"docutils literal\"><span class=\"pre\">[start,</span> <span class=\"pre\">end]</span></code>, the data from <em>start</em> day to\n(<em>end</em> - 1) day of data in <code class=\"docutils literal\"><span class=\"pre\">self.dataset</span></code> will be used. Default: <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code></li>\n<li><strong>train_data_length</strong> – The length of train data. If set to <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code>, all data in the split train set will be used.\nIf set to int, the latest <code class=\"docutils literal\"><span class=\"pre\">train_data_length</span></code> days of data will be used as train set. Default: <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code></li>\n<li><strong>test_ratio</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – The ratio of test set as data will be split into train set and test set. Default: 0.1</li>\n<li><strong>closeness_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of closeness data history. The former consecutive <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> time slots\nof data will be used as closeness history. Default: 6</li>\n<li><strong>period_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of period data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> days will be used as period history. Default: 7</li>\n<li><strong>trend_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of trend data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">trend_len</span></code> weeks (every seven days) will be used as trend history. Default: 4</li>\n<li><strong>target_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The numbers of steps that need prediction by one piece of history data. Have to be 1 now.\nDefault: 1</li>\n<li><strong>normalize</strong> (<em>bool|str|object</em>) – Select which normalizer to normalize input data. Default: <code class=\"docutils literal\"><span class=\"pre\">True</span></code></li>\n<li><strong>workday_parser</strong> – Used to build external features to be used in neural methods. Default: <code class=\"docutils literal\"><span class=\"pre\">is_work_day_america</span></code></li>\n<li><strong>with_tpe</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – If <code class=\"docutils literal\"><span class=\"pre\">True</span></code>, data loader will build time position embeddings. Default: <code class=\"docutils literal\"><span class=\"pre\">False</span></code></li>\n<li><strong>data_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><code class=\"xref py py-obj docutils literal\"><span class=\"pre\">str</span></code></a> or <code class=\"docutils literal\"><span class=\"pre\">None</span></code>) – The dataset directory. If set to <code class=\"docutils literal\"><span class=\"pre\">None</span></code>, a directory will be created. If\n<code class=\"docutils literal\"><span class=\"pre\">dataset</span></code> is file path, <code class=\"docutils literal\"><span class=\"pre\">data_dir</span></code> should be <code class=\"docutils literal\"><span class=\"pre\">None</span></code> too. Default: <code class=\"docutils literal\"><span class=\"pre\">None</span></code></li>\n<li><strong>MergeIndex</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The granularity of dataset will be <code class=\"docutils literal\"><span class=\"pre\">MergeIndex</span></code> * original granularity.</li>\n<li><strong>MergeWay</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – How to change the data granularity. Now it can be <code class=\"docutils literal\"><span class=\"pre\">sum</span></code> <code class=\"docutils literal\"><span class=\"pre\">average</span></code> or <code class=\"docutils literal\"><span class=\"pre\">max</span></code>.</li>\n<li><strong>remove</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – If <code class=\"docutils literal\"><span class=\"pre\">True</span></code>, dataloader  will remove stations whose average traffic is less than 1.\nOthewise, dataloader will use all stations.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.dataset\">\n<code class=\"descname\">dataset</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.dataset\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>DataSet</em> – The DataSet object storing basic data.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.daily_slots\">\n<code class=\"descname\">daily_slots</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.daily_slots\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The number of time slots in one single day.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.station_number\">\n<code class=\"descname\">station_number</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.station_number\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The number of nodes.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.external_dim\">\n<code class=\"descname\">external_dim</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.external_dim\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The number of dimensions of external features.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.train_closeness\">\n<code class=\"descname\">train_closeness</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.train_closeness\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>np.ndarray</em> – The closeness history of train set data. When <code class=\"docutils literal\"><span class=\"pre\">with_tpe</span></code> is <code class=\"docutils literal\"><span class=\"pre\">False</span></code>,\nits shape is [train_time_slot_num, <code class=\"docutils literal\"><span class=\"pre\">station_number</span></code>, <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code>, 1].\nOn the dimension of <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code>, data are arranged from earlier time slots to later time slots.\nIf <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> is set to 0, train_closeness will be an empty ndarray.\n<code class=\"docutils literal\"><span class=\"pre\">train_period</span></code>, <code class=\"docutils literal\"><span class=\"pre\">train_trend</span></code>, <code class=\"docutils literal\"><span class=\"pre\">test_closeness</span></code>, <code class=\"docutils literal\"><span class=\"pre\">test_period</span></code>, <code class=\"docutils literal\"><span class=\"pre\">test_trend</span></code> have similar shape\nand construction.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.train_y\">\n<code class=\"descname\">train_y</code><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.train_y\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>np.ndarray</em> – The train set data. Its shape is [train_time_slot_num, <code class=\"docutils literal\"><span class=\"pre\">station_number</span></code>, 1].\n<code class=\"docutils literal\"><span class=\"pre\">test_y</span></code> has similar shape and construction.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.dataset.data_loader.NodeTrafficLoader.make_concat\">\n<code class=\"descname\">make_concat</code><span class=\"sig-paren\">(</span><em>node='all'</em>, <em>is_train=True</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.dataset.data_loader.NodeTrafficLoader.make_concat\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>A function to concatenate all closeness, period and trend history data to use as inputs of models.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>node</strong> (int or <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code>) – To specify the index of certain node. If set to <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code>, return the concatenation\nresult of all nodes. If set to an integer, it will be the index of the selected node. Default: <code class=\"docutils literal\"><span class=\"pre\">'all'</span></code></li>\n<li><strong>is_train</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – If set to <code class=\"docutils literal\"><span class=\"pre\">True</span></code>, <code class=\"docutils literal\"><span class=\"pre\">train_closeness</span></code>, <code class=\"docutils literal\"><span class=\"pre\">train_period</span></code>, and <code class=\"docutils literal\"><span class=\"pre\">train_trend</span></code> will be\nconcatenated. If set to <code class=\"docutils literal\"><span class=\"pre\">False</span></code>, <code class=\"docutils literal\"><span class=\"pre\">test_closeness</span></code>, <code class=\"docutils literal\"><span class=\"pre\">test_period</span></code>, and <code class=\"docutils literal\"><span class=\"pre\">test_trend</span></code> will be\nconcatenated. Default: True</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\">Function returns an ndarray with shape as\n[time_slot_num, <code class=\"docutils literal\"><span class=\"pre\">station_number</span></code>, <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> + <code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> + <code class=\"docutils literal\"><span class=\"pre\">trend_len</span></code>, 1],\nand time_slot_num is the temporal length of train set data if <code class=\"docutils literal\"><span class=\"pre\">is_train</span></code> is <code class=\"docutils literal\"><span class=\"pre\">True</span></code>\nor the temporal length of test set data if <code class=\"docutils literal\"><span class=\"pre\">is_train</span></code> is <code class=\"docutils literal\"><span class=\"pre\">False</span></code>.\nOn the second dimension, data are arranged as\n<code class=\"docutils literal\"><span class=\"pre\">earlier</span> <span class=\"pre\">closeness</span> <span class=\"pre\">-&gt;</span> <span class=\"pre\">later</span> <span class=\"pre\">closeness</span> <span class=\"pre\">-&gt;</span> <span class=\"pre\">earlier</span> <span class=\"pre\">period</span> <span class=\"pre\">-&gt;</span> <span class=\"pre\">later</span> <span class=\"pre\">period</span> <span class=\"pre\">-&gt;</span> <span class=\"pre\">earlier</span> <span class=\"pre\">trend</span> <span class=\"pre\">-&gt;</span> <span class=\"pre\">later</span> <span class=\"pre\">trend</span></code>.</p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">np.ndarray</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.dataset.dataset\">\n<span id=\"uctb-dataset-dataset-module\"></span><h2>6.1.2. UCTB.dataset.dataset module<a class=\"headerlink\" href=\"#module-UCTB.dataset.dataset\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.dataset.dataset.DataSet\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.dataset.dataset.</code><code class=\"descname\">DataSet</code><span class=\"sig-paren\">(</span><em>dataset</em>, <em>MergeIndex</em>, <em>MergeWay</em>, <em>city=None</em>, <em>data_dir=None</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>An object storing basic data from a formatted pickle file.\nSee also <a class=\"reference external\" href=\"./md_file/tutorial.html\">Build your own datasets</a>.\n:param dataset: A string containing path of the dataset pickle file or a string of name of the dataset.\n:type dataset: str\n:param city: <code class=\"docutils literal\"><span class=\"pre\">None</span></code> if dataset is file path, or a string of name of the city. Default: <code class=\"docutils literal\"><span class=\"pre\">None</span></code>\n:type city: str or <code class=\"docutils literal\"><span class=\"pre\">None</span></code>\n:param data_dir: The dataset directory. If set to <code class=\"docutils literal\"><span class=\"pre\">None</span></code>, a directory will be created.</p>\n<blockquote>\n<div>If <code class=\"docutils literal\"><span class=\"pre\">dataset</span></code> is file path, <code class=\"docutils literal\"><span class=\"pre\">data_dir</span></code> should be <code class=\"docutils literal\"><span class=\"pre\">None</span></code> too. Default: <code class=\"docutils literal\"><span class=\"pre\">None</span></code></div></blockquote>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n</tbody>\n</table>\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.data\">\n<code class=\"descname\">data</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.data\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>dict</em> – The data directly from the pickle file. <code class=\"docutils literal\"><span class=\"pre\">data</span></code> may have a <code class=\"docutils literal\"><span class=\"pre\">data['contribute_data']</span></code> dict to\nstore supplementary data.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.time_range\">\n<code class=\"descname\">time_range</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.time_range\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>list</em> – From <code class=\"docutils literal\"><span class=\"pre\">data['TimeRange']</span></code> in the format of [YYYY-MM-DD, YYYY-MM-DD] indicating the time\nrange of the data.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.time_fitness\">\n<code class=\"descname\">time_fitness</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.time_fitness\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – From <code class=\"docutils literal\"><span class=\"pre\">data['TimeFitness']</span></code> indicating how many minutes is a single time slot.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.node_traffic\">\n<code class=\"descname\">node_traffic</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.node_traffic\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>np.ndarray</em> – Data recording the main stream data of the nodes in during the time range.\nFrom <code class=\"docutils literal\"><span class=\"pre\">data['Node']['TrafficNode']</span></code> with shape as [time_slot_num, node_num].</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.node_monthly_interaction\">\n<code class=\"descname\">node_monthly_interaction</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.node_monthly_interaction\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>np.ndarray</em> – Data recording the monthly interaction of pairs of nodes.\nIts shape is [month_num, node_num, node_num].It’s from <code class=\"docutils literal\"><span class=\"pre\">data['Node']['TrafficMonthlyInteraction']</span></code>\nand is used to build interaction graph.\nIts an optional attribute and can be set as an empty list if interaction graph is not needed.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.node_station_info\">\n<code class=\"descname\">node_station_info</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.node_station_info\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>dict</em> – A dict storing the coordinates of nodes. It shall be formatted as {id (may be\narbitrary): [id (when sorted, should be consistant with index of <code class=\"docutils literal\"><span class=\"pre\">node_traffic</span></code>), latitude, longitude,\nother notes]}. It’s from <code class=\"docutils literal\"><span class=\"pre\">data['Node']['StationInfo']</span></code> and is used to build distance graph.\nIts an optional attribute and can be set as an empty list if distance graph is not needed.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.MergeIndex\">\n<code class=\"descname\">MergeIndex</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.MergeIndex\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – A int number that used to adjust the granularity of the dataset, the granularity of the new\ndataset is time_fitness*MergeIndex. default: 1</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.dataset.dataset.DataSet.MergeWay\">\n<code class=\"descname\">MergeWay</code><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.MergeWay\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>str</em> – can be <cite>sum</cite> and <cite>average</cite>.  default: <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>sum</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.dataset.dataset.DataSet.merge_data\">\n<code class=\"descname\">merge_data</code><span class=\"sig-paren\">(</span><em>data</em>, <em>dataType</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.dataset.dataset.DataSet.merge_data\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.preprocess.html\" class=\"btn btn-neutral float-right\" title=\"6.2. UCTB.preprocess package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"APIReference.html\" class=\"btn btn-neutral\" title=\"6. API Reference\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/UCTB.evaluation.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.5. UCTB.evaluation package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.6. UCTB.train package\" href=\"UCTB.train.html\"/>\n        <link rel=\"prev\" title=\"6.4. UCTB.model package\" href=\"UCTB.model.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.5. UCTB.evaluation package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.evaluation.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-evaluation-package\">\n<h1>6.5. UCTB.evaluation package<a class=\"headerlink\" href=\"#uctb-evaluation-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.evaluation.metric\">\n<span id=\"uctb-evaluation-metric-module\"></span><h2>6.5.1. UCTB.evaluation.metric module<a class=\"headerlink\" href=\"#module-UCTB.evaluation.metric\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.mae\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">mae</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=None</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.mae\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Mean Absolute Error (MAE)</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller or equal to threshold in target will be removed in computing the mae</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.mape\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">mape</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=0</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.mape\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Mean Absolute Percentage Error (MAPE)</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller than threshold in target will be removed in computing the mape.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.rmse\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">rmse</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=None</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.rmse\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Root Mean Square Error (RMSE)</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller or equal to threshold in target will be removed in computing the rmse</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.smape\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">smape</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=0</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.smape\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Symmetric Mean Absolute Percentage Error (SMAPE)</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller than threshold in target will be removed in computing the smape.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.trunc_mae\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">trunc_mae</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=0</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.trunc_mae\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><blockquote>\n<div>Mean Absolute Error with Truncation (Trunc_MAE)</div></blockquote>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller or equal to threshold in target will be replaced in computing the mae</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.trunc_rmse\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">trunc_rmse</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=0</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.trunc_rmse\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Root Mean Square Error with Truncation (trunc_RMSE)\n:param prediction: prediction with shape [batch_size, …]\n:type prediction: ndarray\n:param target: same shape with prediction, [batch_size, …]\n:type target: ndarray\n:param threshold: data smaller or equal to threshold in target</p>\n<blockquote>\n<div>will be replaced by threshold in computing the s_rmse</div></blockquote>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.evaluation.metric.trunc_smape\">\n<code class=\"descclassname\">UCTB.evaluation.metric.</code><code class=\"descname\">trunc_smape</code><span class=\"sig-paren\">(</span><em>prediction</em>, <em>target</em>, <em>threshold=0</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.evaluation.metric.trunc_smape\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Symmetric Mean Absolute Percentage Error with Truncation (Trunc_SMAPE)</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>prediction</strong> (<em>ndarray</em>) – prediction with shape [batch_size, …]</li>\n<li><strong>target</strong> (<em>ndarray</em>) – same shape with prediction, [batch_size, …]</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – data smaller than threshold in target will be replaced in computing the trunc_smape.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.train.html\" class=\"btn btn-neutral float-right\" title=\"6.6. UCTB.train package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.model.html\" class=\"btn btn-neutral\" title=\"6.4. UCTB.model package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/UCTB.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>UCTB package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>UCTB package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-package\">\n<h1>UCTB package<a class=\"headerlink\" href=\"#uctb-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"subpackages\">\n<h2>Subpackages<a class=\"headerlink\" href=\"#subpackages\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.dataset.html\">6.1. UCTB.dataset package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.data_loader\">6.1.1. UCTB.dataset.data_loader module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.dataset\">6.1.2. UCTB.dataset.dataset module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.evaluation.html\">6.5. UCTB.evaluation package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.evaluation.html#module-UCTB.evaluation.metric\">6.5.1. UCTB.evaluation.metric module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.model.html\">6.4. UCTB.model package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ARIMA\">6.4.1. UCTB.model.ARIMA module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DCRNN\">6.4.2. UCTB.model.DCRNN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DeepST\">6.4.3. UCTB.model.DeepST module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GeoMAN\">6.4.4. UCTB.model.GeoMAN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.HM\">6.4.5. UCTB.model.HM module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STMeta\">6.4.6. UCTB.model.STMeta module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_MGCN\">6.4.7. UCTB.model.ST_MGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_ResNet\">6.4.8. UCTB.model.ST_ResNet module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.XGBoost\">6.4.9. UCTB.model.XGBoost module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.AGCRN\">6.4.10. UCTB.model.AGCRN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ASTGCN\">6.4.11. UCTB.model.ASTGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GMAN\">6.4.12. UCTB.model.GMAN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#uctb-model-graphwavenet-module\">6.4.13. UCTB.model.GraphWaveNet module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STGCN\">6.4.14. UCTB.model.STGCN module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STSGCN\">6.4.15. UCTB.model.STSGCN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.model_unit.html\">6.3. UCTB.model_unit package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.BaseModel\">6.3.1. UCTB.model_unit.BaseModel module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.DCRNN_CELL\">6.3.2. UCTB.model_unit.DCRNN_CELL module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.GraphModelLayers\">6.3.3. UCTB.model_unit.GraphModelLayers module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.ST_RNN\">6.3.4. UCTB.model_unit.ST_RNN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.preprocess.html\">6.2. UCTB.preprocess package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#uctb-preprocess-graphgenerator-module\">6.2.1. UCTB.preprocess.GraphGenerator module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.preprocessor\">6.2.2. UCTB.preprocess.preprocessor module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.time_utils\">6.2.3. UCTB.preprocess.time_utils module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.train.html\">6.6. UCTB.train package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.EarlyStopping\">6.6.1. UCTB.train.EarlyStopping module</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.MiniBatchTrain\">6.6.2. UCTB.train.MiniBatchTrain module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.utils.html\">6.7. UCTB.utils package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.utils.html#module-UCTB.utils.multi_threads\">6.7.1. UCTB.utils.multi_threads module</a></li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<div class=\"section\" id=\"module-UCTB\">\n<span id=\"module-contents\"></span><h2>Module contents<a class=\"headerlink\" href=\"#module-UCTB\" title=\"Permalink to this headline\">¶</a></h2>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/UCTB.model.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.4. UCTB.model package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.5. UCTB.evaluation package\" href=\"UCTB.evaluation.html\"/>\n        <link rel=\"prev\" title=\"6.3. UCTB.model_unit package\" href=\"UCTB.model_unit.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.4. UCTB.model package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.model.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-model-package\">\n<h1>6.4. UCTB.model package<a class=\"headerlink\" href=\"#uctb-model-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.model.ARIMA\">\n<span id=\"uctb-model-arima-module\"></span><h2>6.4.1. UCTB.model.ARIMA module<a class=\"headerlink\" href=\"#module-UCTB.model.ARIMA\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.ARIMA.ARIMA\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ARIMA.</code><code class=\"descname\">ARIMA</code><span class=\"sig-paren\">(</span><em>time_sequence</em>, <em>order=None</em>, <em>seasonal_order=(0</em>, <em>0</em>, <em>0</em>, <em>0)</em>, <em>max_ar=6</em>, <em>max_ma=4</em>, <em>max_d=2</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ARIMA.ARIMA\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>ARIMA is a generalization of an ARMA (Autoregressive Moving Average) model, used in predicting\nfuture points in time series analysis.</p>\n<p>Since there may be three kinds of series data as closeness, period and trend history, this class\ntrains three different ARIMA models for each node according  to the three kinds of history data,\nand returns average of the predicted values by the models in prediction.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>time_sequence</strong> (<em>array_like</em>) – The observation value of time_series.</li>\n<li><strong>order</strong> (<em>iterable</em>) – It stores the (p, d, q) orders of the model for the number of AR parameters\n, differences, MA parameters. If set to None, ARIMA class will calculate the orders for\neach series based on max_ar, max_ma and max_d. Default: None</li>\n<li><strong>seasonal_order</strong> (<em>iterable</em>) – It stores the (P,D,Q,s) order of the seasonal ARIMA model for the\nAR parameters, differences, MA parameters, and periodicity. <cite>s</cite> is an integer giving the\nperiodicity (number of periods in season).</li>\n<li><strong>max_ar</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Maximum number of AR lags to use. Default: 6</li>\n<li><strong>max_ma</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Maximum number of MA lags to use. Default: 4</li>\n<li><strong>max_d</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Maximum number of degrees of differencing. Default: 2</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"docutils\">\n<dt>Attribute:</dt>\n<dd>order(iterable): (p, d, q) orders for ARIMA model.\nseasonal_order(iterable): (P,D,Q,s) order for seasonal ARIMA model.\nmodel_res(): Fit method for likelihood based models.</dd>\n</dl>\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model.ARIMA.ARIMA.adf_test\">\n<em class=\"property\">static </em><code class=\"descname\">adf_test</code><span class=\"sig-paren\">(</span><em>time_series</em>, <em>max_lags=None</em>, <em>verbose=True</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ARIMA.ARIMA.adf_test\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Augmented Dickey–Fuller test. The Augmented Dickey-Fuller test can be used to test for\na unit root in a univariate process in the presence of serial correlation.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model.ARIMA.ARIMA.get_order\">\n<code class=\"descname\">get_order</code><span class=\"sig-paren\">(</span><em>series</em>, <em>order=None</em>, <em>max_ar=6</em>, <em>max_ma=2</em>, <em>max_d=2</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ARIMA.ARIMA.get_order\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>If order is None, it simply returns order, otherwise, it calculates the (p, d, q) orders\nfor the series data based on max_ar, max_ma and max_d.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model.ARIMA.ARIMA.predict\">\n<code class=\"descname\">predict</code><span class=\"sig-paren\">(</span><em>time_sequences</em>, <em>forecast_step=1</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ARIMA.ARIMA.predict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><dl class=\"docutils\">\n<dt>Argues:</dt>\n<dd>time_sequences: The input time_series features.\nforecast_step: The number of predicted future steps. Default: 1</dd>\n</dl>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">Prediction results with shape of (len(time_sequence)/forecast_step,forecast_step=,1).</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">np.ndarray</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.DCRNN\">\n<span id=\"uctb-model-dcrnn-module\"></span><h2>6.4.2. UCTB.model.DCRNN module<a class=\"headerlink\" href=\"#module-UCTB.model.DCRNN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.DCRNN.DCRNN\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.DCRNN.</code><code class=\"descname\">DCRNN</code><span class=\"sig-paren\">(</span><em>num_node</em>, <em>num_diffusion_matrix</em>, <em>num_rnn_units=64</em>, <em>num_rnn_layers=1</em>, <em>max_diffusion_step=2</em>, <em>seq_len=6</em>, <em>use_curriculum_learning=False</em>, <em>input_dim=1</em>, <em>output_dim=1</em>, <em>cl_decay_steps=1000</em>, <em>target_len=1</em>, <em>lr=0.0001</em>, <em>epsilon=0.001</em>, <em>optimizer_name='Adam'</em>, <em>code_version='DCRNN-QuickStart'</em>, <em>model_dir='model_dir'</em>, <em>gpu_device='0'</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.DCRNN.DCRNN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://arxiv.org/pdf/1707.01926.pdf\">Diffusion convolutional recurrent neural network: Data-driven traffic forecasting (Li Yaguang, et al., 2017)</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/liyaguang/DCRNN\">A TensorFlow implementation of Diffusion Convolutional Recurrent Neural Network (liyaguang)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of nodes in the graph, e.g. number of stations in NYC-Bike dataset.</li>\n<li><strong>num_diffusion_matrix</strong> – Number of diffusion matrix used in model.</li>\n<li><strong>num_rnn_units</strong> – Number of RNN units.</li>\n<li><strong>num_rnn_layers</strong> – Number of RNN layers</li>\n<li><strong>max_diffusion_step</strong> – Number of diffusion steps</li>\n<li><strong>seq_len</strong> – Input sequence length</li>\n<li><strong>use_curriculum_learning</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – model’s prediction (True) or the previous ground truth in training (False).</li>\n<li><strong>input_dim</strong> – Dimension of the input feature</li>\n<li><strong>output_dim</strong> – Dimension of the output feature</li>\n<li><strong>cl_decay_steps</strong> – When use_curriculum_learning=True, cl_decay_steps is used to adjust the ratio of using ground\ntrue labels, where with more training steps, the ratio drops.</li>\n<li><strong>target_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Output sequence length.</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate</li>\n<li><strong>epsilon</strong> – epsilon in Adam</li>\n<li><strong>optimizer_name</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – ‘sgd’ or ‘Adam’ optimizer</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code, which will be used as filename for saving the model</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’.</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.DCRNN.DCRNN.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><em>init_vars=True</em>, <em>max_to_keep=5</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.DCRNN.DCRNN.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.DeepST\">\n<span id=\"uctb-model-deepst-module\"></span><h2>6.4.3. UCTB.model.DeepST module<a class=\"headerlink\" href=\"#module-UCTB.model.DeepST\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.DeepST.DeepST\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.DeepST.</code><code class=\"descname\">DeepST</code><span class=\"sig-paren\">(</span><em>closeness_len</em>, <em>period_len</em>, <em>trend_len</em>, <em>width</em>, <em>height</em>, <em>external_dim</em>, <em>kernel_size=3</em>, <em>num_conv_filters=64</em>, <em>lr=1e-05</em>, <em>code_version='QuickStart-DeepST'</em>, <em>model_dir='model_dir'</em>, <em>gpu_device='0'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.DeepST.DeepST\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<p>Deep learning-based prediction model for Spatial-Temporal data (DeepST)</p>\n<p>DeepST is composed of three components: 1) temporal dependent\ninstances: describing temporal closeness, period and seasonal\ntrend; 2) convolutional neural networks: capturing near and\nfar spatial dependencies; 3) early and late fusions: fusing\nsimilar and different domains’ data.</p>\n<dl class=\"docutils\">\n<dt>Reference:</dt>\n<dd><ul class=\"first last simple\">\n<li><a class=\"reference external\" href=\"https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf\">DNN-Based Prediction Model for Spatial-Temporal Data (Junbo Zhang et al., 2016)</a>.</li>\n</ul>\n</dd>\n</dl>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>closeness_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of closeness data history. The former consecutive <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> time slots\nof data will be used as closeness history.</li>\n<li><strong>period_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of period data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> days will be used as period history.</li>\n<li><strong>trend_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of trend data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">trend_len</span></code> weeks (every seven days) will be used as trend history.</li>\n<li><strong>width</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The width of grid data.</li>\n<li><strong>height</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The height of grid data.</li>\n<li><strong>externai_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of dimensions of external data.</li>\n<li><strong>kernel_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Kernel size in Convolutional neural networks. Default: 3</li>\n<li><strong>num_conv_filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – the Number of filters in the convolution. Default: 64</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate. Default: 1e-5</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code.</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.DeepST.DeepST.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.DeepST.DeepST.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.GeoMAN\">\n<span id=\"uctb-model-geoman-module\"></span><h2>6.4.4. UCTB.model.GeoMAN module<a class=\"headerlink\" href=\"#module-UCTB.model.GeoMAN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.GeoMAN.GeoMAN\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.GeoMAN.</code><code class=\"descname\">GeoMAN</code><span class=\"sig-paren\">(</span><em>total_sensers</em>, <em>input_dim</em>, <em>external_dim</em>, <em>output_dim</em>, <em>input_steps</em>, <em>output_steps</em>, <em>n_stacked_layers=2</em>, <em>n_encoder_hidden_units=128</em>, <em>n_decoder_hidden_units=128</em>, <em>dropout_rate=0.3</em>, <em>lr=0.001</em>, <em>gc_rate=2.5</em>, <em>code_version='GeoMAN-QuickStart'</em>, <em>model_dir='model_dir'</em>, <em>gpu_device='0'</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GeoMAN.GeoMAN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<p>Multi-level Attention Networks for Geo-sensory Time Series Prediction (GeoMAN)</p>\n<p>GeoMAN consists of two major parts: 1) A multi-level attention mechanism (including both local and global\nspatial attentions in encoder and temporal attention in decoder) to model the dynamic spatio-temporal\ndependencies; 2) A general fusion module to incorporate the external factors from different domains (e.g.,\nmeteorology, time of day and land use).</p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2018/0476.pdf\">GeoMAN: Multi-level Attention Networks for Geo-sensory Time Series Prediction (Liang Yuxuan, et al., 2018)</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/yoshall/GeoMAN\">An easy implement of GeoMAN using TensorFlow (yoshall &amp; CastleLiang)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>total_sensers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of total sensors used in global attention mechanism.</li>\n<li><strong>input_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of dimensions of the target sensor’s input.</li>\n<li><strong>external_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of dimensions of the external features.</li>\n<li><strong>output_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of dimensions of the target sensor’s output.</li>\n<li><strong>input_steps</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of historical input data, a.k.a, input timesteps.</li>\n<li><strong>output_steps</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of steps that need prediction by one piece of history data, a.k.a, output\ntimesteps. Have to be 1 now.</li>\n<li><strong>n_stacked_layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of LSTM layers stacked in both encoder and decoder (These two are the\nsame). Default: 2</li>\n<li><strong>n_encoder_hidden_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of hidden units in each layer of encoder. Default: 128</li>\n<li><strong>n_decoder_hidden_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of hidden units in each layer of decoder. Default: 128</li>\n<li><strong>dropout_rate</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Dropout rate of LSTM layers in both encoder and decoder. Default: 0.3</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate. Default: 0.001</li>\n<li><strong>gc_rate</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – A clipping ratio for all the gradients. This operation normalizes all gradients so that\ntheir L2-norms are less than or equal to <code class=\"docutils literal\"><span class=\"pre\">gc_rate</span></code>. Default: 2.5</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code. Default: ‘GeoMAN-QuickStart’</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’</li>\n<li><strong>**kwargs</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#dict\" title=\"(in Python v3.12)\"><em>dict</em></a>) – Reserved for future use. May be used to pass parameters to class <code class=\"docutils literal\"><span class=\"pre\">BaseModel</span></code>.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.GeoMAN.GeoMAN.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><em>init_vars=True</em>, <em>max_to_keep=5</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GeoMAN.GeoMAN.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GeoMAN.input_transform\">\n<code class=\"descclassname\">UCTB.model.GeoMAN.</code><code class=\"descname\">input_transform</code><span class=\"sig-paren\">(</span><em>local_features</em>, <em>global_features</em>, <em>external_features</em>, <em>targets</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GeoMAN.input_transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Split the model’s inputs from matrices to lists on timesteps axis.</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GeoMAN.split_timesteps\">\n<code class=\"descclassname\">UCTB.model.GeoMAN.</code><code class=\"descname\">split_timesteps</code><span class=\"sig-paren\">(</span><em>inputs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GeoMAN.split_timesteps\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Split the input matrix from (batch, timesteps, input_dim) to a step list ([[batch, input_dim], …, ]).</p>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.HM\">\n<span id=\"uctb-model-hm-module\"></span><h2>6.4.5. UCTB.model.HM module<a class=\"headerlink\" href=\"#module-UCTB.model.HM\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.HM.HM\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.HM.</code><code class=\"descname\">HM</code><span class=\"sig-paren\">(</span><em>c</em>, <em>p</em>, <em>t</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.HM.HM\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Historical Mean. A naive method that simply return average of hisrory data of each time slot.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>c</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of time slots of closeness history.</li>\n<li><strong>p</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of time slots of period history which presents daily feature.</li>\n<li><strong>t</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of time slots of trend history which presents weekly feature.</li>\n<li><strong>that `</strong> (<em>Note</em>) – </li>\n<li><strong>should be considerd in average.</strong> (<em>features</em>) – </li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.HM.HM.predict\">\n<code class=\"descname\">predict</code><span class=\"sig-paren\">(</span><em>closeness_feature</em>, <em>period_feature</em>, <em>trend_feature</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.HM.HM.predict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Give closeness, period and trend history values and then use their averages as predict.</p>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.STMeta\">\n<span id=\"uctb-model-stmeta-module\"></span><h2>6.4.6. UCTB.model.STMeta module<a class=\"headerlink\" href=\"#module-UCTB.model.STMeta\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.STMeta.STMeta\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.STMeta.</code><code class=\"descname\">STMeta</code><span class=\"sig-paren\">(</span><em>num_node</em>, <em>external_dim</em>, <em>closeness_len</em>, <em>period_len</em>, <em>trend_len</em>, <em>input_dim=1</em>, <em>num_graph=1</em>, <em>gcn_k=1</em>, <em>gcn_layers=1</em>, <em>gclstm_layers=1</em>, <em>num_hidden_units=64</em>, <em>num_dense_units=32</em>, <em>graph_merge_gal_units=32</em>, <em>graph_merge_gal_num_heads=2</em>, <em>temporal_merge_gal_units=64</em>, <em>temporal_merge_gal_num_heads=2</em>, <em>st_method='GCLSTM'</em>, <em>temporal_merge='gal'</em>, <em>graph_merge='gal'</em>, <em>output_activation=&lt;function sigmoid&gt;</em>, <em>lr=0.0001</em>, <em>code_version='STMeta-QuickStart'</em>, <em>model_dir='model_dir'</em>, <em>gpu_device='0'</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STMeta.STMeta\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of nodes in the graph, e.g. number of stations in NYC-Bike dataset.</li>\n<li><strong>external_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Dimension of the external feature, e.g. temperature and wind are two dimension.</li>\n<li><strong>closeness_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of closeness data history. The former consecutive <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> time slots</li>\n<li><strong>data will be used as closeness history.</strong> (<em>of</em>) – </li>\n<li><strong>period_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of period data history. The data of exact same time slots in former consecutive</li>\n<li><strong>days will be used as period history.</strong> (<em>period_len</em>) – </li>\n<li><strong>trend_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of trend data history. The data of exact same time slots in former consecutive</li>\n<li><strong>weeks</strong> (<em>trend_len</em>) – </li>\n<li><strong>input_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The dimension of input features. 1 if “with_tpe” (data_loader parameters) = False, otherwise 0.</li>\n<li><strong>num_graph</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of graphs used in STMeta.</li>\n<li><strong>gcn_k</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The highest order of Chebyshev Polynomial approximation in GCN.</li>\n<li><strong>gcn_layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of GCN layers.</li>\n<li><strong>gclstm_layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of STRNN layers, it works on all modes of STMeta such as GCLSTM and DCRNN.</li>\n<li><strong>num_hidden_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of hidden units of RNN.</li>\n<li><strong>num_dense_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of dense units.</li>\n<li><strong>graph_merge_gal_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of units in GAL for merging different graph features.\nOnly works when graph_merge=’gal’</li>\n<li><strong>graph_merge_gal_num_heads</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of heads in GAL for merging different graph features.\nOnly works when graph_merge=’gal’</li>\n<li><strong>temporal_merge_gal_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of units in GAL for merging different temporal features.\nOnly works when temporal_merge=’gal’</li>\n<li><strong>temporal_merge_gal_num_heads</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of heads in GAL for merging different temporal features.\nOnly works when temporal_merge=’gal’</li>\n<li><strong>st_method</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – must in [‘GCLSTM’, ‘DCRNN’, ‘GRU’, ‘LSTM’], which refers to different\nspatial-temporal modeling methods.\n‘GCLSTM’: GCN for modeling spatial feature, LSTM for modeling temporal feature.\n‘DCRNN’: Diffusion Convolution for modeling spatial feature, GRU for modeling temporam frature.\n‘GRU’: Ignore the spatial, and model the temporal feature using GRU\n‘LSTM’: Ignore the spatial, and model the temporal feature using LSTM</li>\n<li><strong>temporal_merge</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – must in [‘gal’, ‘concat’], refers to different temporal merging methods,\n‘gal’: merge using GAL,\n‘concat’: merge by concat and dense</li>\n<li><strong>graph_merge</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – must in [‘gal’, ‘concat’], refers to different graph merging methods,\n‘gal’: merge using GAL,\n‘concat’: merge by concat and dense</li>\n<li><strong>output_activation</strong> (<em>function</em>) – activation function, e.g. tf.nn.tanh</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate. Default: 1e-5</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code, which will be used as filename for saving the model</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’.</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.STMeta.STMeta.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><em>init_vars=True</em>, <em>max_to_keep=5</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STMeta.STMeta.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.ST_MGCN\">\n<span id=\"uctb-model-st-mgcn-module\"></span><h2>6.4.7. UCTB.model.ST_MGCN module<a class=\"headerlink\" href=\"#module-UCTB.model.ST_MGCN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.ST_MGCN.ST_MGCN\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ST_MGCN.</code><code class=\"descname\">ST_MGCN</code><span class=\"sig-paren\">(</span><em>T</em>, <em>input_dim</em>, <em>num_graph</em>, <em>gcl_k</em>, <em>gcl_l</em>, <em>lstm_units</em>, <em>lstm_layers</em>, <em>lr</em>, <em>external_dim</em>, <em>code_version</em>, <em>model_dir</em>, <em>gpu_device</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ST_MGCN.ST_MGCN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"http://www-scf.usc.edu/~yaguang/papers/aaai19_multi_graph_convolution.pdf\">Spatiotemporal multi-graph convolution network for ride-hailing demand forecasting (Geng Xu, et al., 2019)</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/shawnwang-tech/ST-MGCN-pytorch\">A PyTorch implementation of the ST-MGCN model  (shawnwang-tech)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>T</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Input sequence length</li>\n<li><strong>input_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Input feature dimension</li>\n<li><strong>num_graph</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of graphs used in the model.</li>\n<li><strong>gcl_k</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The highest order of Chebyshev Polynomial approximation in GCN.</li>\n<li><strong>gcl_l</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of GCN layers.</li>\n<li><strong>lstm_units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of hidden units of RNN.</li>\n<li><strong>lstm_layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of LSTM layers.</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate</li>\n<li><strong>external_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Dimension of the external feature, e.g. temperature and wind are two dimension.</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code, which will be used as filename for saving the model</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’.</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ST_MGCN.ST_MGCN.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><em>init_vars=True</em>, <em>max_to_keep=5</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ST_MGCN.ST_MGCN.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.ST_ResNet\">\n<span id=\"uctb-model-st-resnet-module\"></span><h2>6.4.8. UCTB.model.ST_ResNet module<a class=\"headerlink\" href=\"#module-UCTB.model.ST_ResNet\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.ST_ResNet.ST_ResNet\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ST_ResNet.</code><code class=\"descname\">ST_ResNet</code><span class=\"sig-paren\">(</span><em>width</em>, <em>height</em>, <em>external_dim</em>, <em>closeness_len</em>, <em>period_len</em>, <em>trend_len</em>, <em>num_residual_unit=4</em>, <em>kernel_size=3</em>, <em>lr=5e-05</em>, <em>model_dir='model_dir'</em>, <em>code_version='QuickStart'</em>, <em>conv_filters=64</em>, <em>gpu_device='0'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ST_ResNet.ST_ResNet\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\" title=\"UCTB.model_unit.BaseModel.BaseModel\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel</span></code></a></p>\n<p>ST-ResNet is a deep-learning model with an end-to-end structure\nbased on unique properties of spatio-temporal data making use of convolution and residual units.</p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://arxiv.org/pdf/1610.00081.pdf\">Deep Spatio-Temporal Residual Networks for Citywide Crowd Flows Prediction (Junbo Zhang et al., 2016)</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/lucktroy/DeepST/tree/master/scripts/papers/AAAI17\">Github repository (lucktroy)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>width</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The width of grid data.</li>\n<li><strong>height</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The height of grid data.</li>\n<li><strong>externai_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of dimensions of external data.</li>\n<li><strong>closeness_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of closeness data history. The former consecutive <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> time slots\nof data will be used as closeness history.</li>\n<li><strong>period_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of period data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> days will be used as period history.</li>\n<li><strong>trend_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of trend data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">trend_len</span></code> weeks (every seven days) will be used as trend history.</li>\n<li><strong>num_residual_unit</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of residual units. Default: 4</li>\n<li><strong>kernel_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Kernel size in Convolutional neural networks. Default: 3</li>\n<li><strong>lr</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Learning rate. Default: 1e-5</li>\n<li><strong>code_version</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Current version of this model code.</li>\n<li><strong>model_dir</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – The directory to store model files. Default:’model_dir’</li>\n<li><strong>conv_filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – the Number of filters in the convolution. Default: 64</li>\n<li><strong>gpu_device</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – To specify the GPU to use. Default: ‘0’</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ST_ResNet.ST_ResNet.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ST_ResNet.ST_ResNet.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.XGBoost\">\n<span id=\"uctb-model-xgboost-module\"></span><h2>6.4.9. UCTB.model.XGBoost module<a class=\"headerlink\" href=\"#module-UCTB.model.XGBoost\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.XGBoost.XGBoost\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.XGBoost.</code><code class=\"descname\">XGBoost</code><span class=\"sig-paren\">(</span><em>n_estimators=10</em>, <em>max_depth=5</em>, <em>verbosity=0</em>, <em>objective='reg:squarederror'</em>, <em>eval_metric='rmse'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.XGBoost.XGBoost\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>XGBoost is an optimized distributed gradient boosting machine learning algorithm.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>*n_estimators</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of boosting iterations. Default: 10</li>\n<li><strong>*max_depth</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Maximum tree depth for base learners. Default: 5</li>\n<li><strong>*verbosity</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The degree of verbosity. Valid values are 0 (silent) - 3 (debug). Default: 0</li>\n<li><strong>*objective</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/string.html#module-string\" title=\"(in Python v3.12)\"><em>string</em></a><em> or </em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#callable\" title=\"(in Python v3.12)\"><em>callable</em></a>) – Specify the learning task and the corresponding learning objective or\na custom objective function to be used. Default: <code class=\"docutils literal\"><span class=\"pre\">'reg:squarederror'</span></code></li>\n<li><strong>*eval_metric</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>list of str</em><em>, or </em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#callable\" title=\"(in Python v3.12)\"><em>callable</em></a><em>, </em><em>optional</em>) – If a str, should be a built-in evaluation metric to use. See more in\n<a class=\"reference external\" href=\"https://xgboost.readthedocs.io/en/latest/python/python_api.html\">API Reference of XGBoost Library</a>.\nDefault: <code class=\"docutils literal\"><span class=\"pre\">'rmse'</span></code></li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.XGBoost.XGBoost.fit\">\n<code class=\"descname\">fit</code><span class=\"sig-paren\">(</span><em>X</em>, <em>y</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.XGBoost.XGBoost.fit\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Training method.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>X</strong> (<em>np.ndarray/scipy.sparse/pd.DataFrame/dt.Frame</em>) – The training input samples.</li>\n<li><strong>y</strong> (<em>np.ndarray</em><em>, </em><em>optional</em>) – The target values of training samples.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model.XGBoost.XGBoost.predict\">\n<code class=\"descname\">predict</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.XGBoost.XGBoost.predict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Prediction method.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">Predicted values with shape as [time_slot_num, node_num, 1].</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\">np.ndarray</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.AGCRN\">\n<span id=\"uctb-model-agcrn-module\"></span><h2>6.4.10. UCTB.model.AGCRN module<a class=\"headerlink\" href=\"#module-UCTB.model.AGCRN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.AGCRN.AGCRN\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.AGCRN.</code><code class=\"descname\">AGCRN</code><span class=\"sig-paren\">(</span><em>num_node</em>, <em>input_dim</em>, <em>hidden_dim</em>, <em>output_dim</em>, <em>pred_step</em>, <em>num_layers</em>, <em>default_graph</em>, <em>embed_dim</em>, <em>cheb_k</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.AGCRN.AGCRN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf\">Adaptive graph convolutional recurrent network for traffic forecasting.</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/LeiBAI/AGCRN\">A PyTorch implementation of the AGCRN model  (LeiBAI)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of nodes.</li>\n<li><strong>input_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Input feature dimension.</li>\n<li><strong>hidden_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of hidden units of RNN.</li>\n<li><strong>output_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of dimension of output.</li>\n<li><strong>pred_step</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of steps to predict.</li>\n<li><strong>num_layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of layers of AGCRNCell.</li>\n<li><strong>default_graph</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – Whether to use default graph or not.</li>\n<li><strong>embed_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of dimension of embedding.</li>\n<li><strong>cheb_k</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Order of chebyshev polynomial.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.ASTGCN\">\n<span id=\"uctb-model-astgcn-module\"></span><h2>6.4.11. UCTB.model.ASTGCN module<a class=\"headerlink\" href=\"#module-UCTB.model.ASTGCN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model.ASTGCN.ASTGCN_submodule\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">ASTGCN_submodule</code><span class=\"sig-paren\">(</span><em>DEVICE</em>, <em>num_blocks</em>, <em>in_channels</em>, <em>K</em>, <em>num_chev_filter</em>, <em>num_time_filter</em>, <em>time_strides</em>, <em>cheb_polynomials</em>, <em>pred_step</em>, <em>len_input</em>, <em>num_node</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.ASTGCN_submodule\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/3881\">Attention based spatial-temporal graph convolutional networks for traffic flow forecasting..</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/guoshnBJTU/ASTGCN-r-pytorch\">A PyTorch implementation of the ASTGCN model  (guoshnBJTU)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>DEVICE</strong> (<em>torch.device</em>) – Which device use to train.</li>\n<li><strong>num_blocks</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of blocks.</li>\n<li><strong>in_channels</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of input channels.</li>\n<li><strong>K</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Order of chebyshev polynomial.</li>\n<li><strong>num_chev_filter</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of chebyshev filter.</li>\n<li><strong>num_time_filter</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of time filter.</li>\n<li><strong>time_strides</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of time strides.</li>\n<li><strong>cheb_polynomials</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Chebyshev Polynomials.</li>\n<li><strong>pred_step</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of steps of prediction.</li>\n<li><strong>len_input</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of steps of sequence input.</li>\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of nodes.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ASTGCN.ASTGCN_submodule.forward\">\n<code class=\"descname\">forward</code><span class=\"sig-paren\">(</span><em>x</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.ASTGCN_submodule.forward\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>x</strong> – (B, N_nodes, F_in, T_in)</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">(B, N_nodes, T_out)</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.model.ASTGCN.Spatial_Attention_layer\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">Spatial_Attention_layer</code><span class=\"sig-paren\">(</span><em>DEVICE</em>, <em>in_channels</em>, <em>num_of_vertices</em>, <em>num_of_timesteps</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.Spatial_Attention_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p>compute spatial attention scores</p>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ASTGCN.Spatial_Attention_layer.forward\">\n<code class=\"descname\">forward</code><span class=\"sig-paren\">(</span><em>x</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.Spatial_Attention_layer.forward\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>x</strong> – (batch_size, N, F_in, T)</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">(B,N,N)</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.model.ASTGCN.cheb_conv\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">cheb_conv</code><span class=\"sig-paren\">(</span><em>K</em>, <em>cheb_polynomials</em>, <em>in_channels</em>, <em>out_channels</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.cheb_conv\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p>K-order chebyshev graph convolution</p>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ASTGCN.cheb_conv.forward\">\n<code class=\"descname\">forward</code><span class=\"sig-paren\">(</span><em>x</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.cheb_conv.forward\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Chebyshev graph convolution operation\n:param x: (batch_size, N, F_in, T)\n:return: (batch_size, N, F_out, T)</p>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.model.ASTGCN.cheb_conv_withSAt\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">cheb_conv_withSAt</code><span class=\"sig-paren\">(</span><em>K</em>, <em>cheb_polynomials</em>, <em>in_channels</em>, <em>out_channels</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.cheb_conv_withSAt\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p>K-order chebyshev graph convolution</p>\n<dl class=\"method\">\n<dt id=\"UCTB.model.ASTGCN.cheb_conv_withSAt.forward\">\n<code class=\"descname\">forward</code><span class=\"sig-paren\">(</span><em>x</em>, <em>spatial_attention</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.cheb_conv_withSAt.forward\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Chebyshev graph convolution operation\n:param x: (batch_size, N, F_in, T)\n:return: (batch_size, N, F_out, T)</p>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.ASTGCN.cheb_polynomial\">\n<code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">cheb_polynomial</code><span class=\"sig-paren\">(</span><em>L_tilde</em>, <em>K</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.cheb_polynomial\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>compute a list of chebyshev polynomials from T_0 to T_{K-1}</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>L_tilde</strong> (<em>scaled Laplacian</em><em>, </em><em>np.ndarray</em><em>, </em><em>shape</em><em> (</em><em>N</em><em>, </em><em>N</em><em>)</em>) – </li>\n<li><strong>K</strong> (<em>the maximum order of chebyshev polynomials</em>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"><strong>cheb_polynomials</strong></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\"><a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\">list</a>(np.ndarray), length: K, from T_0 to T_{K-1}</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.ASTGCN.make_model\">\n<code class=\"descclassname\">UCTB.model.ASTGCN.</code><code class=\"descname\">make_model</code><span class=\"sig-paren\">(</span><em>DEVICE</em>, <em>nb_block</em>, <em>in_channels</em>, <em>K</em>, <em>nb_chev_filter</em>, <em>nb_time_filter</em>, <em>time_strides</em>, <em>L_tilde</em>, <em>num_for_predict</em>, <em>len_input</em>, <em>num_of_vertices</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.ASTGCN.make_model\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>DEVICE</strong> – </li>\n<li><strong>nb_block</strong> – </li>\n<li><strong>in_channels</strong> – </li>\n<li><strong>K</strong> – </li>\n<li><strong>nb_chev_filter</strong> – </li>\n<li><strong>nb_time_filter</strong> – </li>\n<li><strong>time_strides</strong> – </li>\n<li><strong>cheb_polynomials</strong> – </li>\n<li><strong>nb_predict_step</strong> – </li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<p>:param len_input\n:return:</p>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.GMAN\">\n<span id=\"uctb-model-gman-module\"></span><h2>6.4.12. UCTB.model.GMAN module<a class=\"headerlink\" href=\"#module-UCTB.model.GMAN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.GMAN\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">GMAN</code><span class=\"sig-paren\">(</span><em>X</em>, <em>TE</em>, <em>SE</em>, <em>P</em>, <em>Q</em>, <em>T</em>, <em>L</em>, <em>K</em>, <em>d</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.GMAN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><blockquote>\n<div><p>References:\n- <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>Gman: A graph multi-attention network for traffic prediction.</p>\n<blockquote>\n<div>&lt;<a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5477\">https://ojs.aaai.org/index.php/AAAI/article/view/5477</a>&gt;`_.</div></blockquote>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://github.com/zhengchuanpan/GMAN\">A Tensorflow implementation of the GMAN model  (Zhengchuanpan)</a>.</li>\n</ul>\n</div></blockquote>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>P</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of history steps.</li>\n<li><strong>Q</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of prediction steps.</li>\n<li><strong>T</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of steps which one day is divided into.</li>\n<li><strong>L</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of STAtt blocks in the encoder/decoder.</li>\n<li><strong>K</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of attention heads.</li>\n<li><strong>d</strong> – Number of dimension of each attention head outputs.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.STEmbedding\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">STEmbedding</code><span class=\"sig-paren\">(</span><em>SE</em>, <em>TE</em>, <em>T</em>, <em>D</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.STEmbedding\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>spatio-temporal embedding</p>\n<p>SE:      [N, D]\nTE:      [batch_size, P + Q, 2] (dayofweek, timeofday)\nT:        num of time steps in one day\nD:        output dims\nretrun: [batch_size, P + Q, N, D]</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.alias_draw\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">alias_draw</code><span class=\"sig-paren\">(</span><em>J</em>, <em>q</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.alias_draw\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Draw sample from a non-uniform discrete distribution using alias sampling.</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.alias_setup\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">alias_setup</code><span class=\"sig-paren\">(</span><em>probs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.alias_setup\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Compute utility lists for non-uniform sampling from discrete distributions.\nRefer to <a class=\"reference external\" href=\"https://hips.seas.harvard.edu/blog/2013/03/03/the-alias-method-efficient-sampling-with-many-discrete-outcomes/\">https://hips.seas.harvard.edu/blog/2013/03/03/the-alias-method-efficient-sampling-with-many-discrete-outcomes/</a>\nfor details</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.gatedFusion\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">gatedFusion</code><span class=\"sig-paren\">(</span><em>HS</em>, <em>HT</em>, <em>D</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.gatedFusion\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>gated fusion</p>\n<p>HS:      [batch_size, num_step, N, D]\nHT:      [batch_size, num_step, N, D]\nD:        output dims\nreturn: [batch_size, num_step, N, D]</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.spatialAttention\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">spatialAttention</code><span class=\"sig-paren\">(</span><em>X</em>, <em>STE</em>, <em>K</em>, <em>d</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.spatialAttention\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>spatial attention mechanism</p>\n<p>X:        [batch_size, num_step, N, D]\nSTE:    [batch_size, num_step, N, D]\nK:        number of attention heads\nd:        dimension of each attention outputs\nreturn: [batch_size, num_step, N, D]</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.temporalAttention\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">temporalAttention</code><span class=\"sig-paren\">(</span><em>X</em>, <em>STE</em>, <em>K</em>, <em>d</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em>, <em>mask=True</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.temporalAttention\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>temporal attention mechanism</p>\n<p>X:        [batch_size, num_step, N, D]\nSTE:    [batch_size, num_step, N, D]\nK:        number of attention heads\nd:        dimension of each attention outputs\nreturn: [batch_size, num_step, N, D]</p>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.GMAN.transformAttention\">\n<code class=\"descclassname\">UCTB.model.GMAN.</code><code class=\"descname\">transformAttention</code><span class=\"sig-paren\">(</span><em>X</em>, <em>STE_P</em>, <em>STE_Q</em>, <em>K</em>, <em>d</em>, <em>bn</em>, <em>bn_decay</em>, <em>is_training</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GMAN.transformAttention\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>transform attention mechanism</p>\n<p>X:        [batch_size, P, N, D]\nSTE_P:  [batch_size, P, N, D]\nSTE_Q:  [batch_size, Q, N, D]\nK:        number of attention heads\nd:        dimension of each attention outputs\nreturn: [batch_size, Q, N, D]</p>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"uctb-model-graphwavenet-module\">\n<h2>6.4.13. UCTB.model.GraphWaveNet module<a class=\"headerlink\" href=\"#uctb-model-graphwavenet-module\" title=\"Permalink to this headline\">¶</a></h2>\n<span class=\"target\" id=\"module-UCTB.model.GraphWaveNet\"></span><dl class=\"class\">\n<dt id=\"UCTB.model.GraphWaveNet.gwnet\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model.GraphWaveNet.</code><code class=\"descname\">gwnet</code><span class=\"sig-paren\">(</span><em>device</em>, <em>num_node</em>, <em>dropout=0.3</em>, <em>supports=None</em>, <em>gcn_bool=True</em>, <em>addaptadj=True</em>, <em>aptinit=None</em>, <em>in_dim=2</em>, <em>out_dim=12</em>, <em>residual_channels=32</em>, <em>dilation_channels=32</em>, <em>skip_channels=256</em>, <em>end_channels=512</em>, <em>kernel_size=2</em>, <em>blocks=4</em>, <em>layers=2</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.GraphWaveNet.gwnet\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">torch.nn.modules.module.Module</span></code></p>\n<p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2019/0264.pdf\">Graph wavenet for deep spatial-temporal graph modeling.</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/nnzhan/Graph-WaveNet\">A PyTorch implementation of the GraphWaveNet model  (nnzhan)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>device</strong> (<em>torch.device</em>) – Which device use to train.</li>\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of blocks.</li>\n<li><strong>drop_out</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of input channels.</li>\n<li><strong>supports</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Order of chebyshev polynomial.</li>\n<li><strong>gcn_bool</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of chebyshev filter.</li>\n<li><strong>addaptadj</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – Whether to add adaptive adjacent matrix.</li>\n<li><strong>aptinit</strong> (<em>torch.tensor</em>) – Initialization of adjacent matrix.</li>\n<li><strong>in_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of input’s dimension.</li>\n<li><strong>out_dim</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of output’s dimension.</li>\n<li><strong>residual_channels</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of channels after residual module.</li>\n<li><strong>dilation_channels</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of channels after dilation module.</li>\n<li><strong>skip_channels</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of skip channels.</li>\n<li><strong>end_channels</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of end channels.</li>\n<li><strong>kernel_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Kernel Size for dilation convolution.</li>\n<li><strong>blocks</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of block.</li>\n<li><strong>layers</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of layer.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.STGCN\">\n<span id=\"uctb-model-stgcn-module\"></span><h2>6.4.14. UCTB.model.STGCN module<a class=\"headerlink\" href=\"#module-UCTB.model.STGCN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.build_model\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">build_model</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>n_his</em>, <em>Ks</em>, <em>Kt</em>, <em>blocks</em>, <em>keep_prob</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.build_model\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2018/0505.pdf\">Spatio-temporal graph convolutional networks: A deep learning framework for traffic forecasting.</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/VeritasYin/STGCN_IJCAI-18\">A Tensorflow implementation of the STGCN model  (VeritasYin)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>inputs</strong> – Placeholder.</li>\n<li><strong>n_his</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Size of historical records for training.</li>\n<li><strong>Ks</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Kernel size of spatial convolution.</li>\n<li><strong>Kt</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Kernel size of temporal convolution.</li>\n<li><strong>blocks</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – Channel configs of st_conv blocks.</li>\n<li><strong>keep_prob</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Placeholder.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.cheb_poly_approx\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">cheb_poly_approx</code><span class=\"sig-paren\">(</span><em>L</em>, <em>Ks</em>, <em>n</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.cheb_poly_approx\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Chebyshev polynomials approximation function.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>L</strong> – np.matrix, [n_route, n_route], graph Laplacian.</li>\n<li><strong>Ks</strong> – int, kernel size of spatial convolution.</li>\n<li><strong>n</strong> – int, number of routes / size of graph.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">np.ndarray, [n_route, Ks*n_route].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.fully_con_layer\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">fully_con_layer</code><span class=\"sig-paren\">(</span><em>x</em>, <em>n</em>, <em>channel</em>, <em>scope</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.fully_con_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Fully connected layer: maps multi-channels to one.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, [batch_size, 1, n_route, channel].</li>\n<li><strong>n</strong> – int, number of route / size of graph.</li>\n<li><strong>channel</strong> – channel size of input x.</li>\n<li><strong>scope</strong> – str, variable scope.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, 1, n_route, 1].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.gconv\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">gconv</code><span class=\"sig-paren\">(</span><em>x</em>, <em>theta</em>, <em>Ks</em>, <em>c_in</em>, <em>c_out</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.gconv\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><dl class=\"docutils\">\n<dt>Spectral-based graph convolution function.</dt>\n<dd>x: tensor, [batch_size, n_route, c_in].\ntheta: tensor, [Ks*c_in, c_out], trainable kernel parameters.\nKs: int, kernel size of graph convolution.\nc_in: int, size of input channel.\nc_out: int, size of output channel.</dd>\n</dl>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">tensor, [batch_size, n_route, c_out].</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.gen_batch\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">gen_batch</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>batch_size</em>, <em>dynamic_batch=False</em>, <em>shuffle=False</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.gen_batch\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Data iterator in batch.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>inputs</strong> – np.ndarray, [len_seq, n_frame, n_route, C_0], standard sequence units.</li>\n<li><strong>batch_size</strong> – int, the size of batch.</li>\n<li><strong>dynamic_batch</strong> – bool, whether changes the batch size in the last batch if its length is less than the default.</li>\n<li><strong>shuffle</strong> – bool, whether shuffle the batches.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.layer_norm\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">layer_norm</code><span class=\"sig-paren\">(</span><em>x</em>, <em>scope</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.layer_norm\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Layer normalization function.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, [batch_size, time_step, n_route, channel].</li>\n<li><strong>scope</strong> – str, variable scope.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, time_step, n_route, channel].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.output_layer\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">output_layer</code><span class=\"sig-paren\">(</span><em>x</em>, <em>T</em>, <em>scope</em>, <em>act_func='GLU'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.output_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Output layer: temporal convolution layers attach with one fully connected layer,\nwhich map outputs of the last st_conv block to a single-step prediction.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, [batch_size, time_step, n_route, channel].</li>\n<li><strong>T</strong> – int, kernel size of temporal convolution.</li>\n<li><strong>scope</strong> – str, variable scope.</li>\n<li><strong>act_func</strong> – str, activation function.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, 1, n_route, 1].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.spatio_conv_layer\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">spatio_conv_layer</code><span class=\"sig-paren\">(</span><em>x</em>, <em>Ks</em>, <em>c_in</em>, <em>c_out</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.spatio_conv_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Spatial graph convolution layer.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, [batch_size, time_step, n_route, c_in].</li>\n<li><strong>Ks</strong> – int, kernel size of spatial convolution.</li>\n<li><strong>c_in</strong> – int, size of input channel.</li>\n<li><strong>c_out</strong> – int, size of output channel.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, time_step, n_route, c_out].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.st_conv_block\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">st_conv_block</code><span class=\"sig-paren\">(</span><em>x</em>, <em>Ks</em>, <em>Kt</em>, <em>channels</em>, <em>scope</em>, <em>keep_prob</em>, <em>act_func='GLU'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.st_conv_block\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Spatio-temporal convolutional block, which contains two temporal gated convolution layers\nand one spatial graph convolution layer in the middle.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, batch_size, time_step, n_route, c_in].</li>\n<li><strong>Ks</strong> – int, kernel size of spatial convolution.</li>\n<li><strong>Kt</strong> – int, kernel size of temporal convolution.</li>\n<li><strong>channels</strong> – list, channel configs of a single st_conv block.</li>\n<li><strong>scope</strong> – str, variable scope.</li>\n<li><strong>keep_prob</strong> – placeholder, prob of dropout.</li>\n<li><strong>act_func</strong> – str, activation function.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, time_step, n_route, c_out].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.temporal_conv_layer\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">temporal_conv_layer</code><span class=\"sig-paren\">(</span><em>x</em>, <em>Kt</em>, <em>c_in</em>, <em>c_out</em>, <em>act_func='relu'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.temporal_conv_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Temporal convolution layer.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>x</strong> – tensor, [batch_size, time_step, n_route, c_in].</li>\n<li><strong>Kt</strong> – int, kernel size of temporal convolution.</li>\n<li><strong>c_in</strong> – int, size of input channel.</li>\n<li><strong>c_out</strong> – int, size of output channel.</li>\n<li><strong>act_func</strong> – str, activation function.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">tensor, [batch_size, time_step-Kt+1, n_route, c_out].</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STGCN.variable_summaries\">\n<code class=\"descclassname\">UCTB.model.STGCN.</code><code class=\"descname\">variable_summaries</code><span class=\"sig-paren\">(</span><em>var</em>, <em>v_name</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STGCN.variable_summaries\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Attach summaries to a Tensor (for TensorBoard visualization).\nRef: <a class=\"reference external\" href=\"https://zhuanlan.zhihu.com/p/33178205\">https://zhuanlan.zhihu.com/p/33178205</a></p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>var</strong> – tf.Variable().</li>\n<li><strong>v_name</strong> – str, name of the variable.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model.STSGCN\">\n<span id=\"uctb-model-stsgcn-module\"></span><h2>6.4.15. UCTB.model.STSGCN module<a class=\"headerlink\" href=\"#module-UCTB.model.STSGCN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.construct_adj\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">construct_adj</code><span class=\"sig-paren\">(</span><em>A</em>, <em>steps</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.construct_adj\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>construct a bigger adjacency matrix using the given matrix</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>A</strong> (<em>np.ndarray</em><em>, </em><em>adjacency matrix</em><em>, </em><em>shape is</em><em> (</em><em>N</em><em>, </em><em>N</em><em>)</em>) – </li>\n<li><strong>steps</strong> (<em>how many times of the does the new adj mx bigger than A</em>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"><strong>new adjacency matrix</strong></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">csr_matrix, shape is (N * steps, N * steps)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.gcn_operation\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">gcn_operation</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>num_of_filter</em>, <em>num_of_features</em>, <em>num_of_vertices</em>, <em>activation</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.gcn_operation\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>graph convolutional operation, a simple GCN we defined in paper</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>B</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>adj</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>3N</em><em>)</em>) – </li>\n<li><strong>num_of_filter</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C'</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'GLU'</em><em>, </em><em>'relu'}</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (3N, B, C’)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.get_adjacency_matrix\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">get_adjacency_matrix</code><span class=\"sig-paren\">(</span><em>distance_df_filename</em>, <em>num_of_vertices</em>, <em>type_='connectivity'</em>, <em>id_filename=None</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.get_adjacency_matrix\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>distance_df_filename</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>path of the csv file contains edges information</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>the number of vertices</em>) – </li>\n<li><strong>type</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{connectivity</em><em>, </em><em>distance}</em>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"><strong>A</strong></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">np.ndarray, adjacency matrix</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.output_layer\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">output_layer</code><span class=\"sig-paren\">(</span><em>data</em>, <em>num_of_vertices</em>, <em>input_length</em>, <em>num_of_features</em>, <em>num_of_filters=128</em>, <em>predict_length=12</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.output_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>B</em><em>, </em><em>T</em><em>, </em><em>N</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>input_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of time series</em><em>, </em><em>T</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>num_of_filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C'</em>) – </li>\n<li><strong>predict_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of predicted time series</em><em>, </em><em>T'</em>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (B, T’, N)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.position_embedding\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">position_embedding</code><span class=\"sig-paren\">(</span><em>data</em>, <em>input_length</em>, <em>num_of_vertices</em>, <em>embedding_size</em>, <em>temporal=True</em>, <em>spatial=True</em>, <em>init=&lt;mxnet.initializer.Xavier object&gt;</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.position_embedding\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>B</em><em>, </em><em>T</em><em>, </em><em>N</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>input_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of time series</em><em>, </em><em>T</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>embedding_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>spatial</strong> (<em>temporal</em><em>,</em>) – </li>\n<li><strong>init</strong> (<em>mx.initializer.Initializer</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"><strong>data</strong></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (B, T, N, C)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.sthgcn_layer_individual\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">sthgcn_layer_individual</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>T</em>, <em>num_of_vertices</em>, <em>num_of_features</em>, <em>filters</em>, <em>activation</em>, <em>temporal_emb=True</em>, <em>spatial_emb=True</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.sthgcn_layer_individual\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>STSGCL, multiple individual STSGCMs</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>B</em><em>, </em><em>T</em><em>, </em><em>N</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>adj</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>3N</em><em>)</em>) – </li>\n<li><strong>T</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of time series</em><em>, </em><em>T</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a><em>[</em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>]</em><em>, </em><em>list of C'</em>) – </li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'GLU'</em><em>, </em><em>'relu'}</em>) – </li>\n<li><strong>spatial_emb</strong> (<em>temporal_emb</em><em>,</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (B, T-2, N, C’)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.sthgcn_layer_sharing\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">sthgcn_layer_sharing</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>T</em>, <em>num_of_vertices</em>, <em>num_of_features</em>, <em>filters</em>, <em>activation</em>, <em>temporal_emb=True</em>, <em>spatial_emb=True</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.sthgcn_layer_sharing\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>STSGCL, multiple a sharing STSGCM</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>B</em><em>, </em><em>T</em><em>, </em><em>N</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>adj</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>3N</em><em>)</em>) – </li>\n<li><strong>T</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of time series</em><em>, </em><em>T</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a><em>[</em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>]</em><em>, </em><em>list of C'</em>) – </li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'GLU'</em><em>, </em><em>'relu'}</em>) – </li>\n<li><strong>spatial_emb</strong> (<em>temporal_emb</em><em>,</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (B, T-2, N, C’)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.stsgcl\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">stsgcl</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>T</em>, <em>num_of_vertices</em>, <em>num_of_features</em>, <em>filters</em>, <em>module_type</em>, <em>activation</em>, <em>temporal_emb=True</em>, <em>spatial_emb=True</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.stsgcl\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>STSGCL</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>B</em><em>, </em><em>T</em><em>, </em><em>N</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>adj</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>3N</em><em>)</em>) – </li>\n<li><strong>T</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>length of time series</em><em>, </em><em>T</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a><em>[</em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>]</em><em>, </em><em>list of C'</em>) – </li>\n<li><strong>module_type</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'sharing'</em><em>, </em><em>'individual'}</em>) – </li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'GLU'</em><em>, </em><em>'relu'}</em>) – </li>\n<li><strong>spatial_emb</strong> (<em>temporal_emb</em><em>,</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (B, T-2, N, C’)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.stsgcm\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">stsgcm</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>filters</em>, <em>num_of_features</em>, <em>num_of_vertices</em>, <em>activation</em>, <em>prefix=''</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.stsgcm\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>STSGCM, multiple stacked gcn layers with cropping and max operation</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>data</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>B</em><em>, </em><em>C</em><em>)</em>) – </li>\n<li><strong>adj</strong> (<em>mx.sym.var</em><em>, </em><em>shape is</em><em> (</em><em>3N</em><em>, </em><em>3N</em><em>)</em>) – </li>\n<li><strong>filters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a><em>[</em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>]</em><em>, </em><em>list of C'</em>) – </li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>C</em>) – </li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a><em>, </em><em>N</em>) – </li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a><em>, </em><em>{'GLU'</em><em>, </em><em>'relu'}</em>) – </li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – </li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\"></p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">output shape is (N, B, C’)</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.model.STSGCN.stsgcn\">\n<code class=\"descclassname\">UCTB.model.STSGCN.</code><code class=\"descname\">stsgcn</code><span class=\"sig-paren\">(</span><em>data</em>, <em>adj</em>, <em>label</em>, <em>input_length</em>, <em>num_of_vertices</em>, <em>num_of_features</em>, <em>filter_list</em>, <em>module_type</em>, <em>activation</em>, <em>use_mask=True</em>, <em>mask_init_value=None</em>, <em>temporal_emb=True</em>, <em>spatial_emb=True</em>, <em>prefix=''</em>, <em>rho=1</em>, <em>predict_length=12</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model.STSGCN.stsgcn\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p class=\"rubric\">References</p>\n<ul class=\"simple\">\n<li><a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5438\">Spatial-temporal synchronous graph convolutional networks: A new framework for spatial-temporal network data forecasting.</a>.</li>\n<li><a class=\"reference external\" href=\"https://github.com/Davidham3/STSGCN\">A Mxnet implementation of the stsgcn model  (Davidham3)</a>.</li>\n</ul>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>data</strong> (<em>mxnet.sym</em>) – Input data.</li>\n<li><strong>adj</strong> (<em>mxnet.sym</em>) – Adjacent matrix.</li>\n<li><strong>label</strong> (<em>mxnet.sym</em>) – Prediction label.</li>\n<li><strong>input_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Length of input data.</li>\n<li><strong>num_of_vertices</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of vertices in the graph.</li>\n<li><strong>num_of_features</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of features of each vertice.</li>\n<li><strong>filter_list</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – Filters.</li>\n<li><strong>module_type</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Whether sharing weights.</li>\n<li><strong>activation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Choose which activate function.</li>\n<li><strong>use_mask</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – Whether we use mask.</li>\n<li><strong>mask_init_value</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Initial value of mask.</li>\n<li><strong>temporal_emb</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – Whether to use temporal embedding.</li>\n<li><strong>spatial_emb</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – Whether to use spatial embedding.</li>\n<li><strong>prefix</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – String prefix of mask.</li>\n<li><strong>rho</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Hyperparameters used to calculate huber loss.</li>\n<li><strong>predict_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Length of prediction.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.evaluation.html\" class=\"btn btn-neutral float-right\" title=\"6.5. UCTB.evaluation package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.model_unit.html\" class=\"btn btn-neutral\" title=\"6.3. UCTB.model_unit package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/UCTB.model_unit.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.3. UCTB.model_unit package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.4. UCTB.model package\" href=\"UCTB.model.html\"/>\n        <link rel=\"prev\" title=\"6.2. UCTB.preprocess package\" href=\"UCTB.preprocess.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.3. UCTB.model_unit package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.model_unit.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-model-unit-package\">\n<h1>6.3. UCTB.model_unit package<a class=\"headerlink\" href=\"#uctb-model-unit-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.model_unit.BaseModel\">\n<span id=\"uctb-model-unit-basemodel-module\"></span><h2>6.3.1. UCTB.model_unit.BaseModel module<a class=\"headerlink\" href=\"#module-UCTB.model_unit.BaseModel\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model_unit.BaseModel.</code><code class=\"descname\">BaseModel</code><span class=\"sig-paren\">(</span><em>code_version</em>, <em>model_dir</em>, <em>gpu_device</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<dl class=\"docutils\">\n<dt>BaseModel is the base class for many models, such as STMeta, ST-MGCN and ST_ResNet,</dt>\n<dd>you can also build your own model using this class. More information can be found in tutorial.</dd>\n</dl>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>code_version</strong> – Current version of this model code, which will be used as filename for saving the model.</li>\n<li><strong>model_dir</strong> – The directory to store model files. Default:’model_dir’.</li>\n<li><strong>gpu_device</strong> – To specify the GPU to use. Default: ‘0’.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.build\">\n<code class=\"descname\">build</code><span class=\"sig-paren\">(</span><em>init_vars=True</em>, <em>max_to_keep=5</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.build\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><dl class=\"docutils\">\n<dt>Args</dt>\n<dd>init_vars(bool): auto init the parameters if set to True, else no parameters will be initialized.\nmax_to_keep: max file to keep, which equals to max_to_keep in tf.train.Saver.</dd>\n</dl>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.close\">\n<code class=\"descname\">close</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.close\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Close the session, release memory.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.fit\">\n<code class=\"descname\">fit</code><span class=\"sig-paren\">(</span><em>sequence_length</em>, <em>output_names=('loss'</em>, <em>)</em>, <em>op_names=('train_op'</em>, <em>)</em>, <em>evaluate_loss_name='loss'</em>, <em>batch_size=64</em>, <em>max_epoch=10000</em>, <em>validate_ratio=0.1</em>, <em>shuffle_data=True</em>, <em>early_stop_method='t-test'</em>, <em>early_stop_length=10</em>, <em>early_stop_patience=0.1</em>, <em>verbose=True</em>, <em>save_model=True</em>, <em>save_model_name=None</em>, <em>auto_load_model=True</em>, <em>return_outputs=False</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.fit\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>sequence_length</strong> – int, the sequence length which is use in mini-batch training</li>\n<li><strong>output_names</strong> – list, [output_tensor1_name, output_tensor1_name, …]</li>\n<li><strong>op_names</strong> – list, [operation1_name, operation2_name, …]</li>\n<li><strong>evaluate_loss_name</strong> – str, should be on of the output_names, evaluate_loss_name was use in\nearly-stopping</li>\n<li><strong>batch_size</strong> – int, default 64, batch size</li>\n<li><strong>max_epoch</strong> – int, default 10000, max number of epochs</li>\n<li><strong>validate_ratio</strong> – float, default 0.1, the ration of data that will be used as validation dataset</li>\n<li><strong>shuffle_data</strong> – bool, default True, whether shuffle data in mini-batch train</li>\n<li><strong>early_stop_method</strong> – should be ‘t-test’ or ‘naive’, both method are explained in train.EarlyStopping</li>\n<li><strong>early_stop_length</strong> – int, must provide when early_stop_method=’t-test’</li>\n<li><strong>early_stop_patience</strong> – int, must provide when early_stop_method=’naive’</li>\n<li><strong>verbose</strong> – Bool, flag to print training information or not</li>\n<li><strong>save_model</strong> – Bool, flog to save model or not</li>\n<li><strong>save_model_name</strong> – String, filename for saving the model, which will overwrite the code_version.</li>\n<li><strong>auto_load_model</strong> – Bool, the “fit” function will automatically load the model from disk, if exists,\nbefore the training. Set to False to disable the auto-loading.</li>\n<li><strong>return_outputs</strong> – Bool, set True to return the training log, otherwise nothing will be returned</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.load\">\n<code class=\"descname\">load</code><span class=\"sig-paren\">(</span><em>subscript</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.load\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>subscript</strong> – String, subscript will be appended to the code version as the model file name,\nand load the corresponding model using this filename</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.load_event_scalar\">\n<code class=\"descname\">load_event_scalar</code><span class=\"sig-paren\">(</span><em>scalar_name='val_loss'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.load_event_scalar\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>scalar_name</strong> – load the corresponding scalar name from tensorboard-file,\ne.g. load_event_scalar(‘val_loss)</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.predict\">\n<code class=\"descname\">predict</code><span class=\"sig-paren\">(</span><em>sequence_length</em>, <em>output_names=('prediction'</em>, <em>)</em>, <em>cache_volume=64</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.predict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>output_names</strong> – list, [output_tensor_name1, output_tensor_name2, …]</li>\n<li><strong>sequence_length</strong> – int, the length of sequence, which is use in mini-batch training</li>\n<li><strong>cache_volume</strong> – int, default 64, we need to set cache_volume if the cache can not hold\nthe whole validation dataset</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<p>:param : return: outputs_dict: dict, like {output_tensor1_name: output_tensor1_value, …}</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.BaseModel.BaseModel.save\">\n<code class=\"descname\">save</code><span class=\"sig-paren\">(</span><em>subscript</em>, <em>global_step</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.BaseModel.BaseModel.save\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>subscript</strong> – String, subscript will be appended to the code version as the model filename,\nand save the corresponding model using this filename</li>\n<li><strong>global_step</strong> – Int, current training steps</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model_unit.DCRNN_CELL\">\n<span id=\"uctb-model-unit-dcrnn-cell-module\"></span><h2>6.3.2. UCTB.model_unit.DCRNN_CELL module<a class=\"headerlink\" href=\"#module-UCTB.model_unit.DCRNN_CELL\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model_unit.DCRNN_CELL.DCGRUCell\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model_unit.DCRNN_CELL.</code><code class=\"descname\">DCGRUCell</code><span class=\"sig-paren\">(</span><em>num_units</em>, <em>input_dim</em>, <em>num_graphs</em>, <em>supports</em>, <em>max_diffusion_step</em>, <em>num_node</em>, <em>num_proj=None</em>, <em>activation=&lt;function tanh&gt;</em>, <em>reuse=None</em>, <em>use_gc_for_ru=True</em>, <em>name=None</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.DCRNN_CELL.DCGRUCell\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">tensorflow.python.ops.rnn_cell_impl.RNNCell</span></code></p>\n<p>Graph Convolution Gated Recurrent Unit cell.</p>\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.DCRNN_CELL.DCGRUCell.call\">\n<code class=\"descname\">call</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.DCRNN_CELL.DCGRUCell.call\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.model_unit.DCRNN_CELL.DCGRUCell.compute_output_shape\">\n<code class=\"descname\">compute_output_shape</code><span class=\"sig-paren\">(</span><em>input_shape</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.DCRNN_CELL.DCGRUCell.compute_output_shape\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.model_unit.DCRNN_CELL.DCGRUCell.output_size\">\n<code class=\"descname\">output_size</code><a class=\"headerlink\" href=\"#UCTB.model_unit.DCRNN_CELL.DCGRUCell.output_size\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.model_unit.DCRNN_CELL.DCGRUCell.state_size\">\n<code class=\"descname\">state_size</code><a class=\"headerlink\" href=\"#UCTB.model_unit.DCRNN_CELL.DCGRUCell.state_size\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model_unit.GraphModelLayers\">\n<span id=\"uctb-model-unit-graphmodellayers-module\"></span><h2>6.3.3. UCTB.model_unit.GraphModelLayers module<a class=\"headerlink\" href=\"#module-UCTB.model_unit.GraphModelLayers\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GAL\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model_unit.GraphModelLayers.</code><code class=\"descname\">GAL</code><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GAL\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>This class provides static methods for adding Graph Attention Layer.</p>\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GAL.add_ga_layer_matrix\">\n<em class=\"property\">static </em><code class=\"descname\">add_ga_layer_matrix</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>units</em>, <em>num_head</em>, <em>activation=&lt;function tanh&gt;</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GAL.add_ga_layer_matrix\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>This method use Multi-head attention technique to add Graph Attention Layer.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>input</strong> (<em>ndarray</em>) – The set of node features data, with shape [batch, num_node, num_featuer].</li>\n<li><strong>unit</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of merge_gal_units used in GAL.</li>\n<li><strong>num_head</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of multi-head used in GAL.</li>\n<li><strong>activation</strong> (<em>function</em>) – activation function. default:tf.nn.tanh.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\">The weight matrix after softmax function.\ngc_output: The final GAL aggregated feature representation from input feature.</p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><p class=\"first last\">alpha</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GAL.add_residual_ga_layer\">\n<em class=\"property\">static </em><code class=\"descname\">add_residual_ga_layer</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>units</em>, <em>num_head</em>, <em>activation=&lt;function tanh&gt;</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GAL.add_residual_ga_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Call the add_ga_layer_matrix function to build the Graph Attention Layer,\nand add the residual layer to optimize the deep neural network.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GAL.attention_merge_weight\">\n<em class=\"property\">static </em><code class=\"descname\">attention_merge_weight</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>units</em>, <em>num_head</em>, <em>activation=&lt;function leaky_relu&gt;</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GAL.attention_merge_weight\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GCL\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model_unit.GraphModelLayers.</code><code class=\"descname\">GCL</code><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GCL\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>This class provides static methods for adding Graph Convolution Layer.</p>\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GCL.add_gc_layer\">\n<em class=\"property\">static </em><code class=\"descname\">add_gc_layer</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>gcn_k</em>, <em>laplacian_matrix</em>, <em>output_size</em>, <em>dtype=tf.float32</em>, <em>use_bias=True</em>, <em>trainable=True</em>, <em>initializer=None</em>, <em>regularizer=None</em>, <em>activation=&lt;function tanh&gt;</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GCL.add_gc_layer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>Input</strong> (<em>ndarray</em>) – The input features with shape [batch, num_node, num_feature].</li>\n<li><strong>gcn_k</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The highest order of Chebyshev Polynomial approximation in GCN.</li>\n<li><strong>laplacian_matrix</strong> (<em>ndarray</em>) – Laplacian matrix used in GCN, with shape [num_node, num_node].</li>\n<li><strong>output_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of output channels.</li>\n<li><strong>dtype</strong> – Data type. default:tf.float32.</li>\n<li><strong>use_bias</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – It determines whether to add bias in the output. default:True.</li>\n<li><strong>trainable</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – It determines whether <cite>weights</cite> tensor can be trained. default:True.</li>\n<li><strong>initializer</strong> – It determines whether the “weight” tensor is initialized. default:None.</li>\n<li><strong>regularizer</strong> – It determines whether the “weight” tensor is regularized. default:None.</li>\n<li><strong>activation</strong> (<em>function</em>) – activation function. default:tf.nn.tanh.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first last\">Returns the result of convolution of <cite>inputs</cite> and <cite>laplacian_matrix</cite></p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.model_unit.GraphModelLayers.GCL.add_multi_gc_layers\">\n<em class=\"property\">static </em><code class=\"descname\">add_multi_gc_layers</code><span class=\"sig-paren\">(</span><em>inputs</em>, <em>gcn_k</em>, <em>gcn_l</em>, <em>output_size</em>, <em>laplacian_matrix</em>, <em>activation=&lt;function tanh&gt;</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.GraphModelLayers.GCL.add_multi_gc_layers\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Call add_gc_layer function to add multi Graph Convolution Layer.`gcn_l` is the number of layers added.</p>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.model_unit.ST_RNN\">\n<span id=\"uctb-model-unit-st-rnn-module\"></span><h2>6.3.4. UCTB.model_unit.ST_RNN module<a class=\"headerlink\" href=\"#module-UCTB.model_unit.ST_RNN\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.model_unit.ST_RNN.GCLSTMCell\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.model_unit.ST_RNN.</code><code class=\"descname\">GCLSTMCell</code><span class=\"sig-paren\">(</span><em>units</em>, <em>num_node</em>, <em>laplacian_matrix</em>, <em>gcn_k=1</em>, <em>gcn_l=1</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.model_unit.ST_RNN.GCLSTMCell\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <code class=\"xref py py-class docutils literal\"><span class=\"pre\">tensorflow.python.keras.layers.recurrent.LSTMCell</span></code></p>\n<p>GCLSTMCell is one of our implemented ST-RNN models in handling the spatial and temporal features.\nWe performed GCN on both LSTM inputs and hidden-states. The code is inherited from tf.keras.layers.LSTMCell,\nthus it can be used almost the same as LSTMCell except that you need to provide the GCN parameters\nin the __init__ function.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>units</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – number of units of LSTM</li>\n<li><strong>num_node</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – number of nodes in the graph</li>\n<li><strong>laplacian_matrix</strong> (<em>ndarray</em>) – laplacian matrix used in GCN, with shape [num_node, num_node]</li>\n<li><strong>gcn_k</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – highest order of Chebyshev Polynomial approximation in GCN</li>\n<li><strong>gcn_l</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – number of GCN layers</li>\n<li><strong>kwargs</strong> – other parameters supported by LSTMCell, such as activation, kernel_initializer … and so on.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.model.html\" class=\"btn btn-neutral float-right\" title=\"6.4. UCTB.model package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.preprocess.html\" class=\"btn btn-neutral\" title=\"6.2. UCTB.preprocess package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/UCTB.preprocess.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.2. UCTB.preprocess package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.3. UCTB.model_unit package\" href=\"UCTB.model_unit.html\"/>\n        <link rel=\"prev\" title=\"6.1. UCTB.dataset package\" href=\"UCTB.dataset.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.2. UCTB.preprocess package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.preprocess.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-preprocess-package\">\n<h1>6.2. UCTB.preprocess package<a class=\"headerlink\" href=\"#uctb-preprocess-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"uctb-preprocess-graphgenerator-module\">\n<h2>6.2.1. UCTB.preprocess.GraphGenerator module<a class=\"headerlink\" href=\"#uctb-preprocess-graphgenerator-module\" title=\"Permalink to this headline\">¶</a></h2>\n<span class=\"target\" id=\"module-UCTB.preprocess.GraphGenerator\"></span><dl class=\"class\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.GraphGenerator.</code><code class=\"descname\">GraphGenerator</code><span class=\"sig-paren\">(</span><em>data_loader</em>, <em>graph='Correlation'</em>, <em>threshold_distance=1000</em>, <em>threshold_correlation=0</em>, <em>threshold_interaction=500</em>, <em>**kwargs</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>This class is used to build graphs.\nAdajacent matrix and lapalace matrix will be stored in self.AM and self.LM.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>data_loader</strong> (<a class=\"reference internal\" href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader\" title=\"UCTB.dataset.data_loader.NodeTrafficLoader\"><em>NodeTrafficLoader</em></a>) – data_loader object.</li>\n<li><strong>graph</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Types of graphs used in neural methods. Graphs should be a subset of { <code class=\"docutils literal\"><span class=\"pre\">'Correlation'</span></code>,\n<code class=\"docutils literal\"><span class=\"pre\">'Distance'</span></code>, <code class=\"docutils literal\"><span class=\"pre\">'Interaction'</span></code>, <code class=\"docutils literal\"><span class=\"pre\">'Line'</span></code>, <code class=\"docutils literal\"><span class=\"pre\">'Neighbor'</span></code>, <code class=\"docutils literal\"><span class=\"pre\">'Transfer'</span></code> } and concatenated by <code class=\"docutils literal\"><span class=\"pre\">'-'</span></code>,\nand <em>dataset</em> should have data of selected graphs. Default: <code class=\"docutils literal\"><span class=\"pre\">'Correlation'</span></code></li>\n<li><strong>threshold_distance</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Used in building of distance graph. If distance of two nodes in meters is larger\nthan <code class=\"docutils literal\"><span class=\"pre\">threshold_distance</span></code>, the corresponding position of the distance graph will be 1 and otherwise\n0.the corresponding Default: 1000</li>\n<li><strong>threshold_correlation</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Used in building of correlation graph. If the Pearson correlation coefficient is\nlarger than <code class=\"docutils literal\"><span class=\"pre\">threshold_correlation</span></code>, the corresponding position of the correlation graph will be 1\nand otherwise 0. Default: 0</li>\n<li><strong>threshold_interaction</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – Used in building of interatction graph. If in the latest 12 months, the number of\ntimes of interaction between two nodes is larger than <code class=\"docutils literal\"><span class=\"pre\">threshold_interaction</span></code>, the corresponding position\nof the interaction graph will be 1 and otherwise 0. Default: 500</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"attribute\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.AM\">\n<code class=\"descname\">AM</code><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.AM\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>array</em> – Adajacent matrices of graphs.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.LM\">\n<code class=\"descname\">LM</code><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.LM\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>array</em> – Laplacian matrices of graphs.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.adjacent_to_laplacian\">\n<em class=\"property\">static </em><code class=\"descname\">adjacent_to_laplacian</code><span class=\"sig-paren\">(</span><em>adjacent_matrix</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.adjacent_to_laplacian\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Turn adjacent_matrix into Laplace matrix.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.correlation_adjacent\">\n<em class=\"property\">static </em><code class=\"descname\">correlation_adjacent</code><span class=\"sig-paren\">(</span><em>traffic_data</em>, <em>threshold</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.correlation_adjacent\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Calculate correlation graph based on pearson coefficient.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>traffic_data</strong> (<em>ndarray</em>) – numpy array with shape [sequence_length, num_node].</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – float between [-1, 1], nodes with Pearson Correlation coefficient\nlarger than this threshold will be linked together.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.distance_adjacent\">\n<code class=\"descname\">distance_adjacent</code><span class=\"sig-paren\">(</span><em>lat_lng_list</em>, <em>threshold</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.distance_adjacent\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Calculate distance graph based on geographic distance.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>lat_lng_list</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – A list of geographic locations. The format of each element\nin the list is [latitude, longitude].</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – (meters) nodes with geographic distacne smaller than this\nthreshold will be linked together.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.haversine\">\n<em class=\"property\">static </em><code class=\"descname\">haversine</code><span class=\"sig-paren\">(</span><em>lat1</em>, <em>lon1</em>, <em>lat2</em>, <em>lon2</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.haversine\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Calculate the great circle distance between two points\non the earth (specified in decimal degrees)</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.GraphGenerator.GraphGenerator.interaction_adjacent\">\n<em class=\"property\">static </em><code class=\"descname\">interaction_adjacent</code><span class=\"sig-paren\">(</span><em>interaction_matrix</em>, <em>threshold</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.GraphGenerator.interaction_adjacent\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Binarize interaction_matrix based on threshold.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>interaction_matrix</strong> (<em>ndarray</em>) – <p>with shape [num_node, num_node], where each\nelement represents the number of interactions during a certain time,</p>\n<blockquote>\n<div>e.g. 6 monthes, between the corresponding nodes.</div></blockquote>\n</li>\n<li><strong>threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a><em> or </em><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – nodes with number of interactions between them\ngreater than this threshold will be linked together.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.GraphGenerator.scaled_Laplacian_ASTGCN\">\n<code class=\"descclassname\">UCTB.preprocess.GraphGenerator.</code><code class=\"descname\">scaled_Laplacian_ASTGCN</code><span class=\"sig-paren\">(</span><em>W</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.scaled_Laplacian_ASTGCN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>compute     ilde{L}</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>W</strong><strong>(</strong><strong>np.ndarray</strong><strong>)</strong> (<em>shape is</em><em> (</em><em>num_node</em><em>, </em><em>num_node</em><em>)</em><em></em>) – </td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><strong>scaled_Laplacian_ASTGCN</strong></td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\">np.ndarray, shape (num_node, num_node)</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.GraphGenerator.scaled_laplacian_STGCN\">\n<code class=\"descclassname\">UCTB.preprocess.GraphGenerator.</code><code class=\"descname\">scaled_laplacian_STGCN</code><span class=\"sig-paren\">(</span><em>W</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.GraphGenerator.scaled_laplacian_STGCN\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Normalized graph Laplacian function.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>W</strong> (<em>np.ndarray</em>) – [num_node, num_node], weighted adjacency matrix of G.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">Scaled laplacian matrix.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">np.matrix, [num_node, num_node].</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.preprocess.preprocessor\">\n<span id=\"uctb-preprocess-preprocessor-module\"></span><h2>6.2.2. UCTB.preprocess.preprocessor module<a class=\"headerlink\" href=\"#module-UCTB.preprocess.preprocessor\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.MaxMinNormalizer\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">MaxMinNormalizer</code><span class=\"sig-paren\">(</span><em>X</em>, <em>method='all'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.MaxMinNormalizer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"#UCTB.preprocess.preprocessor.Normalizer\" title=\"UCTB.preprocess.preprocessor.Normalizer\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.preprocess.preprocessor.Normalizer</span></code></a></p>\n<p>This class can help normalize and denormalize data using maximum and minimum of data by calling transform and inverse_transform method.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>X</strong> (<em>ndarray</em>) – Data which normalizer extracts characteristics from.</li>\n<li><strong>method</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Parameter to choose in which way the input data will be processed.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.MaxMinNormalizer.inverse_transform\">\n<code class=\"descname\">inverse_transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.MaxMinNormalizer.inverse_transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Restore normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – normalized data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">denormalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.MaxMinNormalizer.transform\">\n<code class=\"descname\">transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.MaxMinNormalizer.transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Process input data to obtain normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – input data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">normalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.Normalizer\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">Normalizer</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.Normalizer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/abc.html#abc.ABC\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">abc.ABC</span></code></a></p>\n<p>Normalizer is the base abstract class for many normalizers such as MaxMinNormalizer and ZscoreNormalizer.You can also build your own normalizer by inheriting this class.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – Data which normalizer extracts characteristics from.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.ST_MoveSample\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">ST_MoveSample</code><span class=\"sig-paren\">(</span><em>closeness_len</em>, <em>period_len</em>, <em>trend_len</em>, <em>target_length=1</em>, <em>daily_slots=24</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.ST_MoveSample\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>This class can converts raw data into temporal features including closenss, period and trend features.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>closeness_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of closeness data history. The former consecutive <code class=\"docutils literal\"><span class=\"pre\">closeness_len</span></code> time slots\nof data will be used as closeness history.</li>\n<li><strong>period_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of period data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> days will be used as period history.</li>\n<li><strong>trend_len</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of trend data history. The data of exact same time slots in former consecutive\n<code class=\"docutils literal\"><span class=\"pre\">trend_len</span></code> weeks (every seven days) will be used as trend history.</li>\n<li><strong>target_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The numbers of steps that need prediction by one piece of history data. Have to be 1 now.\nDefault: 1 default:1.</li>\n<li><strong>daily_slots</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of records of one day. Calculated by 24 * 60 /time_fitness. default:24.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.ST_MoveSample.move_sample\">\n<code class=\"descname\">move_sample</code><span class=\"sig-paren\">(</span><em>data</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.ST_MoveSample.move_sample\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Input data to generate closeness, period, trend features and target vector y.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>data</strong> (<em>ndarray</em>) – Orginal temporal data.</td>\n</tr>\n</tbody>\n</table>\n<p>:return:closeness, period, trend and y matrices.\n:type: numpy.ndarray.</p>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.SplitData\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">SplitData</code><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.SplitData\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>This class can help split data by calling split_data and split_feed_dict method.</p>\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.preprocessor.SplitData.split_data\">\n<em class=\"property\">static </em><code class=\"descname\">split_data</code><span class=\"sig-paren\">(</span><em>data</em>, <em>ratio_list</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.SplitData.split_data\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Divide the data based on the given parameter ratio_list.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>data</strong> (<em>ndarray</em>) – Data to be split.</li>\n<li><strong>ratio_list</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – Split ratio, the <cite>data</cite> will be split according to the ratio.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"docutils\">\n<dt>:return:The elements in the returned list are the divided data, and the</dt>\n<dd>dimensions of the list are the same as ratio_list.</dd>\n</dl>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">list</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.preprocess.preprocessor.SplitData.split_feed_dict\">\n<em class=\"property\">static </em><code class=\"descname\">split_feed_dict</code><span class=\"sig-paren\">(</span><em>feed_dict</em>, <em>sequence_length</em>, <em>ratio_list</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.SplitData.split_feed_dict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Divide the <cite>value</cite> data in <cite>feed_dict</cite> based on the given parameter ratio_list.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>feed_dict</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#dict\" title=\"(in Python v3.12)\"><em>dict</em></a>) – It is a dictionary composed of <cite>key-value</cite> pairs.</li>\n<li><strong>sequence_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – If the length of <cite>value</cite> in <cite>feed_dict</cite> is equal to sequence_length,\nthen this method divides the <cite>value</cite> according to the ratio without changing its <cite>key</cite>.</li>\n<li><strong>ratio_list</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – Split ratio, the data will be split according to the ratio.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\">The elements in the returned list are divided dictionaries, and the dimensions of the list are the same as ratio_list.</p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\"><p class=\"first last\">list</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.WhiteNormalizer\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">WhiteNormalizer</code><span class=\"sig-paren\">(</span><em>X</em>, <em>method='all'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.WhiteNormalizer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"#UCTB.preprocess.preprocessor.Normalizer\" title=\"UCTB.preprocess.preprocessor.Normalizer\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.preprocess.preprocessor.Normalizer</span></code></a></p>\n<p>This class’s normalization won’t do anything.</p>\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.WhiteNormalizer.inverse_transform\">\n<code class=\"descname\">inverse_transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.WhiteNormalizer.inverse_transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Restore normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – normalized data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">denormalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.WhiteNormalizer.transform\">\n<code class=\"descname\">transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.WhiteNormalizer.transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Process input data to obtain normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – input data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">normalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.preprocess.preprocessor.ZscoreNormalizer\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">ZscoreNormalizer</code><span class=\"sig-paren\">(</span><em>X</em>, <em>method='all'</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.ZscoreNormalizer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference internal\" href=\"#UCTB.preprocess.preprocessor.Normalizer\" title=\"UCTB.preprocess.preprocessor.Normalizer\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">UCTB.preprocess.preprocessor.Normalizer</span></code></a></p>\n<p>This class can help normalize and denormalize data using mean and standard deviation in data by calling transform and inverse_transform method.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>X</strong> (<em>ndarray</em>) – Data which normalizer extracts characteristics from.</li>\n<li><strong>method</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str\" title=\"(in Python v3.12)\"><em>str</em></a>) – Parameter to choose in which way the input data will be processed.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.ZscoreNormalizer.inverse_transform\">\n<code class=\"descname\">inverse_transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.ZscoreNormalizer.inverse_transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Restore normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – normalized data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">denormalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.preprocess.preprocessor.ZscoreNormalizer.transform\">\n<code class=\"descname\">transform</code><span class=\"sig-paren\">(</span><em>X</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.ZscoreNormalizer.transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Process input data to obtain normalized data.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>X</strong> (<em>ndarray</em>) – input data.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">normalized data.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\">numpy.ndarray.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.preprocessor.chooseNormalizer\">\n<code class=\"descclassname\">UCTB.preprocess.preprocessor.</code><code class=\"descname\">chooseNormalizer</code><span class=\"sig-paren\">(</span><em>in_arg</em>, <em>X_train</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.preprocessor.chooseNormalizer\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Choose a proper normalizer consistent with user’s input.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first simple\">\n<li><strong>in_arg</strong> (<em>str|bool|object</em>) – Function is based on it to choose different normalizer.</li>\n<li><strong>X_train</strong> (<em>numpy.ndarray</em>) – Function is based on it to initialize the normalizer.</li>\n</ul>\n</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><p class=\"first\">The normalizer consistent with definition.</p>\n</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Type:</th><td class=\"field-body\"><p class=\"first last\">object.</p>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.preprocess.time_utils\">\n<span id=\"uctb-preprocess-time-utils-module\"></span><h2>6.2.3. UCTB.preprocess.time_utils module<a class=\"headerlink\" href=\"#module-UCTB.preprocess.time_utils\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.time_utils.is_valid_date\">\n<code class=\"descclassname\">UCTB.preprocess.time_utils.</code><code class=\"descname\">is_valid_date</code><span class=\"sig-paren\">(</span><em>date_str</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.time_utils.is_valid_date\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>date_str</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/string.html#module-string\" title=\"(in Python v3.12)\"><em>string</em></a>) – e.g. 2019-01-01</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">True if date_str is valid date,\notherwise return False.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.time_utils.is_work_day_america\">\n<code class=\"descclassname\">UCTB.preprocess.time_utils.</code><code class=\"descname\">is_work_day_america</code><span class=\"sig-paren\">(</span><em>date</em>, <em>city</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.time_utils.is_work_day_america\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>date</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/string.html#module-string\" title=\"(in Python v3.12)\"><em>string</em></a><em> or </em><a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#module-datetime\" title=\"(in Python v3.12)\"><em>datetime</em></a>) – e.g. 2019-01-01</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">True if date is not holiday in America,\notherwise return False.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n<dl class=\"function\">\n<dt id=\"UCTB.preprocess.time_utils.is_work_day_china\">\n<code class=\"descclassname\">UCTB.preprocess.time_utils.</code><code class=\"descname\">is_work_day_china</code><span class=\"sig-paren\">(</span><em>date</em>, <em>city</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.preprocess.time_utils.is_work_day_china\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>date</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/string.html#module-string\" title=\"(in Python v3.12)\"><em>string</em></a><em> or </em><a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#module-datetime\" title=\"(in Python v3.12)\"><em>datetime</em></a>) – e.g. 2019-01-01</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\">True if date is not holiday in China,\notherwise return False.</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.model_unit.html\" class=\"btn btn-neutral float-right\" title=\"6.3. UCTB.model_unit package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.dataset.html\" class=\"btn btn-neutral\" title=\"6.1. UCTB.dataset package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/UCTB.train.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.6. UCTB.train package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"6.7. UCTB.utils package\" href=\"UCTB.utils.html\"/>\n        <link rel=\"prev\" title=\"6.5. UCTB.evaluation package\" href=\"UCTB.evaluation.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.6. UCTB.train package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.train.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-train-package\">\n<h1>6.6. UCTB.train package<a class=\"headerlink\" href=\"#uctb-train-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.train.EarlyStopping\">\n<span id=\"uctb-train-earlystopping-module\"></span><h2>6.6.1. UCTB.train.EarlyStopping module<a class=\"headerlink\" href=\"#module-UCTB.train.EarlyStopping\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.train.EarlyStopping.</code><code class=\"descname\">EarlyStopping</code><span class=\"sig-paren\">(</span><em>patience</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Early stop if a span of newest records are not better than the current best record.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>patience</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The span of checked newest records.</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping.__record_list\">\n<code class=\"descname\">__record_list</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping.__record_list\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>list</em> – List of records.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping.__best\">\n<code class=\"descname\">__best</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping.__best\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>float</em> – The current best record.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping.__patience\">\n<code class=\"descname\">__patience</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping.__patience\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The span of checked newest records.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping.__p\">\n<code class=\"descname\">__p</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping.__p\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The number of newest records that are worse than the current best record.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStopping.stop\">\n<code class=\"descname\">stop</code><span class=\"sig-paren\">(</span><em>new_value</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStopping.stop\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Append the new record to the record list\nand check if the number of new records than are worse than the best records exceeds the limit.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>new_value</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – The new record generated by the newest model.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><code class=\"docutils literal\"><span class=\"pre\">True</span></code> if the number of new records than are worse than the best records exceeds the limit and\ntriggers early stop, otherwise <code class=\"docutils literal\"><span class=\"pre\">False</span></code>.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\">bool</a></td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.train.EarlyStopping.</code><code class=\"descname\">EarlyStoppingTTest</code><span class=\"sig-paren\">(</span><em>length</em>, <em>p_value_threshold</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Early Stop by t-test.</p>\n<p>T-test is a two-sided test for the null hypothesis that 2 independent samples\nhave identical average (expected) values. This method takes two intervals according to <code class=\"docutils literal\"><span class=\"pre\">length</span></code>\nin the record list and see if they have identical average values. If so, do early stop.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The length of checked interval.</li>\n<li><strong>p_value_threshold</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – The p-value threshold to decide whether to do early stop.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest.__record_list\">\n<code class=\"descname\">__record_list</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest.__record_list\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>list</em> – List of records.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest.__best\">\n<code class=\"descname\">__best</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest.__best\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>float</em> – The current best record.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest.__test_length\">\n<code class=\"descname\">__test_length</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest.__test_length\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>int</em> – The length of checked interval.</p>\n</dd></dl>\n\n<dl class=\"attribute\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest.__p_value_threshold\">\n<code class=\"descname\">__p_value_threshold</code><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest.__p_value_threshold\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p><em>float</em> – The p-value threshold to decide whether to do early stop.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.train.EarlyStopping.EarlyStoppingTTest.stop\">\n<code class=\"descname\">stop</code><span class=\"sig-paren\">(</span><em>new_value</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.EarlyStopping.EarlyStoppingTTest.stop\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Take two intervals in the record list to do t-test.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><strong>new_value</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#float\" title=\"(in Python v3.12)\"><em>float</em></a>) – The new record generated by the newest model.</td>\n</tr>\n<tr class=\"field-even field\"><th class=\"field-name\">Returns:</th><td class=\"field-body\"><code class=\"docutils literal\"><span class=\"pre\">True</span></code> if p value of t-test is smaller than threshold and\ntriggers early stop, otherwise <code class=\"docutils literal\"><span class=\"pre\">False</span></code>.</td>\n</tr>\n<tr class=\"field-odd field\"><th class=\"field-name\">Return type:</th><td class=\"field-body\"><a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\">bool</a></td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n<div class=\"section\" id=\"module-UCTB.train.MiniBatchTrain\">\n<span id=\"uctb-train-minibatchtrain-module\"></span><h2>6.6.2. UCTB.train.MiniBatchTrain module<a class=\"headerlink\" href=\"#module-UCTB.train.MiniBatchTrain\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"class\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchFeedDict\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.train.MiniBatchTrain.</code><code class=\"descname\">MiniBatchFeedDict</code><span class=\"sig-paren\">(</span><em>feed_dict</em>, <em>sequence_length</em>, <em>batch_size</em>, <em>shuffle=True</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchFeedDict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Get small batches of data from dict for training at once.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>feed_dict</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#dict\" title=\"(in Python v3.12)\"><em>dict</em></a>) – Data dictionary consisting of key-value pairs.</li>\n<li><strong>sequence_length</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Only divide value in <cite>feed_dict</cite> whose length is equal\nto <cite>sequence_length</cite> into several batches.</li>\n<li><strong>batch_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of data for one training session.</li>\n<li><strong>shuffle</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – If set <cite>True</cite>, the input dict will be shuffled. default:True.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchFeedDict.get_batch\">\n<code class=\"descname\">get_batch</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.get_batch\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>For the <cite>value</cite> in <cite>feed_dict</cite> whose length is equal to sequence_length, divide the <cite>value</cite>\ninto several batches, and return one batch in order each time. For those whose length is not\nequal to sequence_length, do not change <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>value`and return it directly. There are internal variables\nto record the number of batches currently generated. When the last data is not enough to\ngenerate a batch, a batch of data from the tail is returned.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchFeedDict.restart\">\n<code class=\"descname\">restart</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.restart\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Set the variable that records the number of batches currently generated to 0, so that\nwe can call the <cite>get_batch</cite> method to generate training data in batches from scratch.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchFeedDict.shuffle\">\n<em class=\"property\">static </em><code class=\"descname\">shuffle</code><span class=\"sig-paren\">(</span><em>data</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.shuffle\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrain\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.train.MiniBatchTrain.</code><code class=\"descname\">MiniBatchTrain</code><span class=\"sig-paren\">(</span><em>X</em>, <em>Y</em>, <em>batch_size</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrain\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Get small batches of data for training at once.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>X</strong> (<em>ndarray</em>) – Input features. The first dimension of X should be sample size.</li>\n<li><strong>Y</strong> (<em>ndarray</em>) – Target values. The first dimension of Y should be sample size.</li>\n<li><strong>batch_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of data for one training session.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrain.get_batch\">\n<code class=\"descname\">get_batch</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrain.get_batch\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Returns a batch of X, Y pairs each time. There are internal variables\nto record the number of batches currently generated. When the last data\nis not enough to generate a batch, a batch of data from the tail is returned.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrain.restart\">\n<code class=\"descname\">restart</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrain.restart\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Set the variable that records the number of batches currently generated to 0, so that\nwe can call the <cite>get_batch</cite> method to generate training data in batches from scratch.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrain.shuffle\">\n<em class=\"property\">static </em><code class=\"descname\">shuffle</code><span class=\"sig-paren\">(</span><em>X</em>, <em>Y</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrain.shuffle\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Input (X, Y) pairs, shuffle and return it.</p>\n</dd></dl>\n\n</dd></dl>\n\n<dl class=\"class\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData\">\n<em class=\"property\">class </em><code class=\"descclassname\">UCTB.train.MiniBatchTrain.</code><code class=\"descname\">MiniBatchTrainMultiData</code><span class=\"sig-paren\">(</span><em>data</em>, <em>batch_size</em>, <em>shuffle=True</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Bases: <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#object\" title=\"(in Python v3.12)\"><code class=\"xref py py-class docutils literal\"><span class=\"pre\">object</span></code></a></p>\n<p>Get small batches of data for training at once.</p>\n<table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>data</strong> (<em>ndarray</em>) – Input data. Its first dimension should be sample size.</li>\n<li><strong>batch_size</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – The number of data for one training session.</li>\n<li><strong>shuffle</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#bool\" title=\"(in Python v3.12)\"><em>bool</em></a>) – If set <cite>True</cite>, the input data will be shuffled. default:True.</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.get_batch\">\n<code class=\"descname\">get_batch</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.get_batch\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Returns a batch of data each time. There are internal variables\nto record the number of batches currently generated. When the last data\nis not enough to generate a batch, a batch of data from the tail is returned.</p>\n</dd></dl>\n\n<dl class=\"method\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.restart\">\n<code class=\"descname\">restart</code><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.restart\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Set the variable that records the number of batches currently generated to 0, so that\nwe can call the <cite>get_batch</cite> method to generate training data in batches from scratch.</p>\n</dd></dl>\n\n<dl class=\"staticmethod\">\n<dt id=\"UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.shuffle\">\n<em class=\"property\">static </em><code class=\"descname\">shuffle</code><span class=\"sig-paren\">(</span><em>data</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.shuffle\" title=\"Permalink to this definition\">¶</a></dt>\n<dd></dd></dl>\n\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"UCTB.utils.html\" class=\"btn btn-neutral float-right\" title=\"6.7. UCTB.utils package\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.evaluation.html\" class=\"btn btn-neutral\" title=\"6.5. UCTB.evaluation package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/UCTB.utils.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>6.7. UCTB.utils package &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n        <link rel=\"up\" title=\"6. API Reference\" href=\"APIReference.html\"/>\n        <link rel=\"next\" title=\"7. Benchmark\" href=\"md_file/all_results.html\"/>\n        <link rel=\"prev\" title=\"6.6. UCTB.train package\" href=\"UCTB.train.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n          <li><a href=\"APIReference.html\">6. API Reference</a> &raquo;</li>\n        \n      <li>6.7. UCTB.utils package</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/UCTB.utils.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb-utils-package\">\n<h1>6.7. UCTB.utils package<a class=\"headerlink\" href=\"#uctb-utils-package\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"module-UCTB.utils.multi_threads\">\n<span id=\"uctb-utils-multi-threads-module\"></span><h2>6.7.1. UCTB.utils.multi_threads module<a class=\"headerlink\" href=\"#module-UCTB.utils.multi_threads\" title=\"Permalink to this headline\">¶</a></h2>\n<dl class=\"function\">\n<dt id=\"UCTB.utils.multi_threads.multiple_process\">\n<code class=\"descclassname\">UCTB.utils.multi_threads.</code><code class=\"descname\">multiple_process</code><span class=\"sig-paren\">(</span><em>distribute_list</em>, <em>partition_func</em>, <em>task_func</em>, <em>n_jobs</em>, <em>reduce_func</em>, <em>parameters</em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#UCTB.utils.multi_threads.multiple_process\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><table class=\"docutils field-list\" frame=\"void\" rules=\"none\">\n<col class=\"field-name\" />\n<col class=\"field-body\" />\n<tbody valign=\"top\">\n<tr class=\"field-odd field\"><th class=\"field-name\">Parameters:</th><td class=\"field-body\"><ul class=\"first last simple\">\n<li><strong>distribute_list</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – The “data” list to be partitioned, such as a list of files which will be\ndistributed among different tasks and each task process a part of the files.</li>\n<li><strong>partition_func</strong> (<em>function</em>) – Partition function will be used to cut the distribute_list, it should accept\nthree inputs: distribute_list, i, n_job, where i is the index of jobs (i.e. integer from 0 to n_jobs-1),\nn_jos is the number of threads; partition function should return a data_list for the job_i</li>\n<li><strong>task_func</strong> (<em>function</em>) – Task function, where the inputs are share_queue, locker, data, parameters, no return.\npls refer to the DiDi-Data processing codes for more information.</li>\n<li><strong>n_jobs</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#int\" title=\"(in Python v3.12)\"><em>int</em></a>) – Number of threads</li>\n<li><strong>reduce_func</strong> (<em>function</em>) – Reduce function which combine the outputs from all the threads into one final output.</li>\n<li><strong>parameters</strong> (<a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#list\" title=\"(in Python v3.12)\"><em>list</em></a>) – parameters send to the task function</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n</dd></dl>\n\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"md_file/all_results.html\" class=\"btn btn-neutral float-right\" title=\"7. Benchmark\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"UCTB.train.html\" class=\"btn btn-neutral\" title=\"6.6. UCTB.train package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/_sources/APIReference.rst.txt",
    "content": "API Reference\n====================\n\n.. toctree::\n\n    UCTB.dataset.rst\n\n    UCTB.preprocess.rst\n\n    UCTB.model_unit.rst\n\n    UCTB.model.rst\n\n    UCTB.evaluation.rst\n\n    UCTB.train.rst\n\n    UCTB.utils.rst"
  },
  {
    "path": "docs/sphinx/_build/_sources/UCTB.dataset.rst.txt",
    "content": "UCTB.dataset package\n====================\n\nUCTB.dataset.data\\_loader module\n--------------------------------\n\n.. automodule:: UCTB.dataset.data_loader\n   :members:\n   :show-inheritance:\n\nUCTB.dataset.dataset module\n---------------------------\n\n.. automodule:: UCTB.dataset.dataset\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/UCTB.evaluation.rst.txt",
    "content": "UCTB.evaluation package\n=======================\n\n\nUCTB.evaluation.metric module\n-----------------------------\n\n.. automodule:: UCTB.evaluation.metric\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/UCTB.model.rst.txt",
    "content": "UCTB.model package\n==================\n\nUCTB.model.ARIMA module\n-----------------------\n\n.. automodule:: UCTB.model.ARIMA\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.DCRNN module\n-----------------------\n\n.. automodule:: UCTB.model.DCRNN\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.DeepST module\n------------------------\n\n.. automodule:: UCTB.model.DeepST\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.GeoMAN module\n------------------------\n\n.. automodule:: UCTB.model.GeoMAN\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.HM module\n--------------------\n\n.. automodule:: UCTB.model.HM\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.STMeta module\n------------------------\n\n.. automodule:: UCTB.model.STMeta\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.ST\\_MGCN module\n--------------------------\n\n.. automodule:: UCTB.model.ST_MGCN\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.ST\\_ResNet module\n----------------------------\n\n.. automodule:: UCTB.model.ST_ResNet\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.XGBoost module\n-------------------------\n\n.. automodule:: UCTB.model.XGBoost\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model.AGCRN module\n-------------------------\n\n.. automodule:: UCTB.model.AGCRN\n   :members:\n   :show-inheritance:\n\nUCTB.model.ASTGCN module\n-------------------------\n\n.. automodule:: UCTB.model.ASTGCN\n   :members:\n   :show-inheritance:\n\nUCTB.model.GMAN module\n-------------------------\n\n.. automodule:: UCTB.model.GMAN\n   :members:\n   :show-inheritance:\n\nUCTB.model.GraphWaveNet module\n-------------------------\n\n.. automodule:: UCTB.model.GraphWaveNet\n   :members:\n   :show-inheritance:\n\nUCTB.model.STGCN module\n-------------------------\n\n.. automodule:: UCTB.model.STGCN\n   :members:\n   :show-inheritance:\n\nUCTB.model.STSGCN module\n-------------------------\n\n.. automodule:: UCTB.model.STSGCN\n   :members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/UCTB.model_unit.rst.txt",
    "content": "UCTB.model\\_unit package\n========================\n\n\nUCTB.model\\_unit.BaseModel module\n---------------------------------\n\n.. automodule:: UCTB.model_unit.BaseModel\n   :members:\n   :show-inheritance:\n\nUCTB.model\\_unit.DCRNN\\_CELL module\n-----------------------------------\n\n.. automodule:: UCTB.model_unit.DCRNN_CELL\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model\\_unit.GraphModelLayers module\n----------------------------------------\n\n.. automodule:: UCTB.model_unit.GraphModelLayers\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.model\\_unit.ST\\_RNN module\n-------------------------------\n\n.. automodule:: UCTB.model_unit.ST_RNN\n   :members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/UCTB.preprocess.rst.txt",
    "content": "UCTB.preprocess package\n=======================\n\n\nUCTB.preprocess.GraphGenerator module\n-----------------------------------\n\n.. automodule:: UCTB.preprocess.GraphGenerator\n   :members:\n   :show-inheritance:\n\nUCTB.preprocess.preprocessor module\n-----------------------------------\n\n.. automodule:: UCTB.preprocess.preprocessor\n   :members:\n   :show-inheritance:\n\nUCTB.preprocess.time\\_utils module\n----------------------------------\n\n.. automodule:: UCTB.preprocess.time_utils\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/UCTB.rst.txt",
    "content": "UCTB package\n============\n\nSubpackages\n-----------\n\n.. toctree::\n\n   UCTB.dataset\n   UCTB.evaluation\n   UCTB.model\n   UCTB.model_unit\n   UCTB.preprocess\n   UCTB.train\n   UCTB.utils\n\nModule contents\n---------------\n\n.. automodule:: UCTB\n   :members:\n   :undoc-members:\n   :show-inheritance:\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/UCTB.train.rst.txt",
    "content": "UCTB.train package\n==================\n\nUCTB.train.EarlyStopping module\n-------------------------------\n\n.. automodule:: UCTB.train.EarlyStopping\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nUCTB.train.MiniBatchTrain module\n--------------------------------\n\n.. automodule:: UCTB.train.MiniBatchTrain\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/UCTB.utils.rst.txt",
    "content": "UCTB.utils package\n==================\n\nUCTB.utils.multi\\_threads module\n--------------------------------\n\n.. automodule:: UCTB.utils.multi_threads\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\n\n\n\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/index.rst.txt",
    "content": ".. UCTB documentation master file, created by\n   sphinx-quickstart on Sun Jul 28 23:57:53 2019.\n   You can adapt this file completely to your liking, but it should at least\n   contain the root `toctree` directive.\n\nWelcome to UCTB's documentation!\n================================\n\n.. toctree::\n   :maxdepth: 2\n   :numbered:\n\n   md_file/introduction.md\n\n   md_file/installation.md\n\n   md_file/urban_dataset.md\n\n   md_file/predictive_tool.md\n\n   md_file/visualization_tool.md\n\n   APIReference.rst\n\n   md_file/all_results.md\n\n   md_file/uctb_group.md\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/md_file/all_results.md.txt",
    "content": "#   Benchmark\n\n## Datasets\n\n| Application              |  Bike-sharing   |  Bike-sharing   |  Bike-sharing   |  Ride-sharing   |  Ride-sharing   |      Metro      |      Metro      |       EV        |  Traffic Speed  |  Traffic Speed  |\n| :----------------------- | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |\n| City                     | *New York City* |    *Chicago*    |      *DC*       |     *Xi'an*     |    *Chengdu*    |   *Chongqing*   |   *Shanghai*    |    *Beijing*    |    *METR-LA*    |   *PEMS-BAY*    |\n| Time span                | 2013.03-2017.09 | 2013.07-2017.09 | 2013.07-2017.09 | 2016.10-2016.11 | 2016.10-2016.11 | 2016.08-2017.07 | 2016.07-2016.09 | 2018.03-2018.05 | 2012.03-2012.06 | 2017.01-2017.07 |\n| Number of riding records |   49,100,694    |   13,130,969    |   13,763,675    |    5,922,961    |    8,439,537    |   409,277,117   |   333,149,034   |    1,272,961    |     34,272      |     52,128      |\n| Number of stations       |       820       |       585       |       532       |       256       |       256       |       113       |       288       |       629       |       207       |       325       |\n\nFollowing shows the map-visualization of stations in NYC, Chicago, DC, Xian and Chengdu.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_NYC.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_Chicago.jpg\" style=\"zoom:23%;height:800px;width:800px;\"/> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_DC.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/DiDi_Xian.jpg\" style=\"zoom:23%;height:800px;width:800px;\" />  <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/DiDi_Chengdu.jpg\" style=\"zoom:23%;height:800px;width:800px;\" />\n\n\n\nFollowing shows the map-visualization of stations in Chongqing, Shanghai and Beijing, METR-LA and PEMS-BAY.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Metro_Chongqing.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Metro_Shanghai.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/EV_Beijing.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/METR_LA.png\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/PEMS_BAY.png\" style=\"zoom:23%;height:800px;width:800px;\" />  \n\n## Results\n\nWe conducted experiments on the following datasets at the granularity of 15 minutes, 30 minutes, and 60 minutes respectively. More details and conclusions can be found in the this paper.  [IEEE Xplore](https://ieeexplore.ieee.org/document/9627543), [arXiv](https://arxiv.org/abs/2009.09379)\n\n### 15-minute prediction tasks\n\nThe best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction\n\n|                          |    NYC     |  Chicago   |     DC     |   Xi'an    |  Chengdu   |  Shanghai  | Chongqing  |  METR-LA   |  PEMS-BAY  |\n| :----------------------- | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: |\n| HM (TC)                  |   1.903    |   1.756    |   1.655    |   3.155    |   4.050    |   93.81    |   76.67    |   7.150    |   2.967    |\n| ARIMA (TC)               |   1.874    |   1.784    |   1.689    |   3.088    |   3.948    |   83.54    |   67.11    |   7.028    |   2.869    |\n| LSTM  (TC)               |   1.989    |   1.802    |   1.678    |   3.051    |   3.888    |   80.40    |   55.37    |   6.380    |   2.690    |\n| HM (TM)                  |   1.892    |   1.668    |   1.555    |   2.828    |   3.347    |   49.75    |   45.26    |   8.934    |   3.690    |\n| XGBoost (TM)             |   1.712    |   1.672    |   1.559    |   2.799    |   3.430    |   47.89    |   35.70    |   6.443    |   2.623    |\n| GBRT (TM)                |   1.708    |   1.667    |   1.552    |   2.775    |   3.363    |   44.55    |   33.29    |   6.371    |   2.645    |\n| TMeta-LSTM-GAL (TM)      |   1.818    |   1.623    |   1.540    |   2.917    |   3.286    |   45.88    |   33.34    |   6.156    |   2.544    |\n| DCRNN (TC+SP)            |   1.712    |   1.718    |   1.594    |   2.889    |   3.743    |   56.00    |   37.07    |   6.440    |   5.322    |\n| STGCN (TC+SP)            |   1.738    |   1.806    |   1.630    |   2.789    |   3.453    |   47.40    |   35.19    |   6.236    |   2.493    |\n| GMAN (TC+SP)             | **1.632*** | **1.529**  | **1.355*** |   2.769    |   3.520    |   49.21    |   36.66    |   6.214    |   3.484    |\n| Graph-WaveNet (TC+SP+SD) | **1.644**  | **1.460*** | **1.357**  |   2.764    |   3.442    |   47.84    |   35.04    | **5.270*** |   2.780    |\n| ST-ResNet (TM+SP)        |    ---     |    ---     |    ---     |   2.686    |   3.314    |    ---     |    ---     |    ---     |    ---     |\n| ST-MGCN (TM+SM)          |   1.687    |   1.646    |   1.545    |   2.714    |   3.293    |   46.54    | **32.72**  |   6.645    | **2.426*** |\n| AGCRN-CDW (TM+SD)        |   1.836    |   1.883    |   1.745    |   2.722    |   3.296    |   77.06    |   46.95    |   6.709    |   2.453    |\n| STMeta-GCL-GAL (TM+SM)   |   1.659    |   1.607    |   1.527    |   2.653    | **3.244**  | **41.67**  | **31.39*** | **5.644**  | **2.433**  |\n| STMeta-GCL-CON (TM+SM)   |   1.673    |   1.629    |   1.512    | **2.637*** | **3.241*** |   43.83    |   38.21    |   5.800    |   2.449    |\n| STMeta-DCG-GAL (TM+SM)   |   1.654    |   1.609    |   1.517    | **2.648**  |   3.254    | **40.94*** |   36.90    |   5.788    |   2.446    |\n\n### Results on 30-minute prediction tasks\n\nThe best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction\n\n|                          |    NYC     |  Chicago   |     DC     |   Xi'an    |  Chengdu   |  Shanghai  | Chongqing  |  Beijing   |  METR-LA   |  PEMS-BAY  |\n| :----------------------- | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: |\n| HM (TC)                  |   3.206    |   2.458    |   2.304    |   5.280    |   6.969    |   269.16   |   221.39   |   0.768    |   9.471    |   4.155    |\n| ARIMA (TC)               |   3.178    |   2.428    |   2.228    |   5.035    |   6.618    |   212.01   |   180.53   |   0.755    |   9.230    |   3.936    |\n| LSTM  (TC)               |   3.018    |   2.493    |   2.212    |   4.950    |   6.444    |   195.60   |   104.61   |   0.755    |   7.866    |   3.683    |\n| HM (TM)                  |   2.686    |   2.230    |   1.956    |   4.239    |   4.851    |   108.59   |   74.55    |   0.864    |   9.560    |   3.965    |\n| XGBoost (TM)             |   2.704    |   2.376    |   1.956    |   4.172    |   4.915    |   81.82    |   69.50    |   0.686    |   8.298    |   3.253    |\n| GBRT (TM)                |   2.682    |   2.355    |   1.928    |   4.135    |   4.873    |   83.94    |   72.99    |   0.689    |   8.269    |   3.370    |\n| TMeta-LSTM-GAL (TM)      |   2.511    | **2.133*** |   1.927    |   3.847    |   4.678    |   85.19    |   53.18    |   0.686    |   7.436    |   3.231    |\n| DCRNN (TC+SP)            |   2.618    |   2.246    |   2.118    |   4.529    |   6.258    |   116.15   |   65.72    |   0.757    |   8.562    |   6.198    |\n| STGCN (TC+SP)            |   2.841    |   2.482    |   2.067    |   3.992    |   5.051    |   91.29    |   58.34    |   0.694    |   7.871    |   3.136    |\n| GMAN (TC+SP)             |   2.792    |   2.336    | **1.836*** |   4.026    |   5.293    |   97.58    |   51.37    |   0.764    |   7.276    |   3.688    |\n| Graph-WaveNet (TC+SP+SD) |   2.666    |   2.158    |   1.874    |   3.986    |   5.097    |   92.88    |   52.52    |   0.719    | **6.809*** |   3.589    |\n| ST-ResNet (TM+SP)        |    ---     |    ---     |    ---     |   3.903    |   4.673    |    ---     |    ---     |    ---     |    ---     |    ---     |\n| ST-MGCN (TM+SM)          |   2.513    |   2.177    |   1.903    |   3.886    |   4.732    |   88.76    |   50.96    |   0.691    |   8.079    | **3.042**  |\n| AGCRN-CDW (TM+SD)        |   2.830    |   2.565    |   2.074    |   3.958    |   4.753    |   238.99   |   131.55   |   0.688    |   8.575    | **3.022*** |\n| STMeta-GCL-GAL (TM+SM)   | **2.410*** |   2.170    |   1.856    | **3.808**  |   4.650    | **75.36*** | **49.47**  | **0.670**  |   7.156    |   3.116    |\n| STMeta-GCL-CON (TM+SM)   | **2.411**  | **2.133*** |   1.859    | **3.772*** | **4.613*** |   80.69    |   50.01    | **0.667*** | **6.889*** |   3.204    |\n| STMeta-DCG-GAL (TM+SM)   | **2.411**  |   2.182    | **1.852**  |   3.833    | **4.635**  | **77.49**  | **48.96*** | **0.670**  |   7.184    |   3.187    |\n\n### Results on 60-minute prediction tasks\n\nThe best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction\n\n|                          |    NYC     |  Chicago   |     DC     |   Xi'an    |  Chengdu   |  Shanghai   | Chongqing  |  Beijing   |  METR-LA   |  PEMS-BAY  |\n| :----------------------- | :--------: | :--------: | :--------: | :--------: | :--------: | :---------: | :--------: | :--------: | :--------: | :--------: |\n| HM (TC)                  |   5.814    |   4.143    |   3.485    |   10.136   |   14.145   |   824.94    |   673.55   |   1.178    |   12.303   |   5.779    |\n| ARIMA (TC)               |   5.289    |   3.744    |   3.183    |   9.475    |   13.259   |   676.79    |   578.19   |   0.982    |   11.739   |   5.670    |\n| LSTM  (TC)               |   5.167    |   3.721    |   3.234    |   9.830    |   13.483   |   506.07    |   322.81   |   0.999    |   10.083   |   4.777    |\n| HM (TM)                  |   3.992    |   3.104    |   2.632    |   6.186    |   7.512    |   172.55    |   119.86   |   1.016    |   10.727   |   4.018    |\n| XGBoost (TM)             |   4.102    |   3.003    |   2.643    |   6.733    |   7.592    |   160.38    |   117.05   |   0.834    |   10.299   |   3.703    |\n| GBRT (TM)                |   4.039    |   2.984    |   2.611    |   6.446    |   7.511    |   154.29    |   113.92   |   0.828    |   10.013   |   3.704    |\n| TMeta-LSTM-GAL (TM)      |   3.739    |   2.840    |   2.557    | **5.843**  |   6.949    |   163.31    |   102.86   |   0.840    | **8.670*** |   3.616    |\n| DCRNN (TC+SP)            |   4.187    |   3.081    |   3.016    |   8.203    |   11.444   |   340.25    |   122.31   |   0.989    |   11.121   |   6.920    |\n| STGCN (TC+SP)            |   3.895    |   2.989    |   2.597    |   6.150    |   7.710    |   187.98    |   106.16   |   0.859    |   10.688   |   3.472    |\n| GMAN (TC+SP)             |   4.251    |   2.875    |   2.530    |   7.099    |   13.351   |   193.39    |   117.52   |   0.949    |   10.012   |   3.846    |\n| Graph-WaveNet (TC+SP+SD) |   3.863    |   2.812    | **2.403*** |   6.541    |   8.162    |   186.82    |   102.75   |   0.930    |   9.463    |   4.135    |\n| ST-ResNet (TM+SP)        |    ---     |    ---     |    ---     |   6.075    |   7.155    |     ---     |    ---     |    ---     |    ---     |    ---     |\n| ST-MGCN (TM+SM)          |   3.723    |   2.904    |   2.518    |   5.878    |   7.067    |   159.52    |   104.87   |   0.827    |   10.798   | **3.486**  |\n| AGCRN-CDW (TM+SD)        |   3.795    |   2.935    |   2.580    |   8.835    |   10.275   |   658.12    |   287.41   |   0.844    |   10.728   | **3.381*** |\n| STMeta-GCL-GAL (TM+SM)   | **3.518**  | **2.695**  |   2.405    |   5.871    | **6.858*** |   153.17    | **97.87**  |   0.831    | **8.834**  |   3.514    |\n| STMeta-GCL-CON (TM+SM)   | **3.507*** |   2.739    | **2.404**  | **5.829*** | **6.873**  | **149.05**  |   106.41   | **0.807**  |   9.147    |   3.552    |\n| STMeta-DCG-GAL (TM+SM)   |   3.521    | **2.652*** |   2.423    |   5.908    |   6.904    | **143.18*** | **94.78*** | **0.803*** |   8.993    |   3.500    |\n\n## Implement Details\n\n### Search Space\n\nWe use [nni](https://github.com/microsoft/nni) toolkit to search the best parameters of HM, XGBoost and GBRT model. Search space are following.\n\n|  Model  |                         Search Space                         |\n| :-----: | :----------------------------------------------------------: |\n|   HM    |               `CT: 0~6`, `PT: 0~7`, `TT: 0~4`                |\n|  ARIMA  |                ``CT:168``,`p:3`, `d:0`, `q:0`                |\n| XGBoost | `CT: 0~12`, `PT: 0~14`, `TT: 0~4`, `estimater: 10~200`, `depth: 2~10` |\n|  GBRT   | `CT: 0~12`, `PT: 0~14`, `TT: 0~4`, `estimater: 10~200`, `depth: 2~10` |\n\n### Bike-sharing\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |      NYC       |    Chicago     |       DC       |\n  | :--------: | :------------: | :------------: | :------------: |\n  |     HM     |    `3-1-2`     |    `5-0-4`     |    `3-7-4`     |\n  |  XGBoost   | `8-14-4-32-2`  | `11-13-4-28-2` | `4-14-4-27-2`  |\n  |    GBRT    | `7-13-4-144-1` | `7-15-4-101-2` | `8-11-5-101-2` |\n\n  | 30 minutes |      NYC       |    Chicago    |       DC        |\n  | :--------: | :------------: | :-----------: | :-------------: |\n  |     HM     |    `2-1-2`     |    `3-2-1`    |     `3-1-4`     |\n  |  XGBoost   | `12-8-1-36-3`  | `7-5-2-24-2`  | `12-13-4-27-2`  |\n  |    GBRT    | `12-10-0-72-4` | `9-13-2-91-2` | `13-15-5-140-1` |\n\n  | 60 minutes |      NYC       |    Chicago    |      DC       |\n  | :--------: | :------------: | :-----------: | :-----------: |\n  |     HM     |    `1-1-3`     |    `1-1-1`    |    `2-1-3`    |\n  |  XGBoost   | `13-7-0-103-3` | `11-8-0-35-4` | `11-9-5-28-3` |\n  |    GBRT    | `12-6-1-58-5`  | `11-8-1-92-5` | `11-8-5-54-3` |\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/bike_trial.py) Run Code & Setting.\n\n* [DCRNN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/bike_trial.py) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on  [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [bike_nyc.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_nyc.data.yml) , [bike_chicago.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_chicago.data.yml), [bike_dc.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_dc.data.yml)\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n            ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n            ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n            ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n            ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n            ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n            ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n  ```\n\n  * TMeta-LSTM-GAL\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p graph:Distance,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p graph:Distance,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p graph:Distance,MergeIndex:12')\n  ```\n\n  * STMeta-V1\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  ```\n\n  * STMeta-V2\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  ```\n\n  * STMeta-V3\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  ```\n\n### Ride-sharing\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |   **Xi'an**   |  **Chengdu**   |\n  | :--------: | :-----------: | :------------: |\n  |     HM     |    `5-0-4`    |    `2-7-4`     |\n  |  XGBoost   | `7-14-0-10-4` | `12-14-1-27-3` |\n  |    GBRT    | `11-2-2-45-3` | `13-15-5-39-3` |\n\n  | 30 minutes |  **Xi'an**   |  **Chengdu**   |\n  | :--------: | :----------: | :------------: |\n  |     HM     |   `2-0-2`    |    `1-7-4`     |\n  |  XGBoost   | `9-0-2-25-3` | `9-14-3-16-3`  |\n  |    GBRT    | `9-0-2-80-3` | `10-10-5-34-3` |\n\n  | 60 minutes |   **Xi'an**   |  **Chengdu**  |\n  | :--------: | :-----------: | :-----------: |\n  |     HM     |    `1-1-2`    |    `0-7-4`    |\n  |  XGBoost   | `12-0-2-10-5` | `9-6-2-14-3`  |\n  |    GBRT    | `9-0-2-50-2`  | `9-12-2-50-5` |\n\n* ST-ResNet\n\n  |                    ST-ResNet Search Space                    |\n  | :----------------------------------------------------------: |\n  | ``residual_units:2~6``,  `conv_filter:[32, 64, 128]`,  `kernal_size:3~5`, <br />`lr:[0.0001, 0.00002, 0.00004, 0.00008, 0.00001]`, `batch_size:[32, 64, 128, 256]` |\n\n  The best parameters found are following.\n\n  ```python\n  args = {\n    'dataset': 'DiDi',\n    'city': 'Chengdu',\n    'num_residual_unit': 4,\n    'conv_filters': 64,\n    'kernel_size': 3,\n    'lr': 1e-5,\n    'batch_size': 32\n  \n  ```\n\n  We can modify `city` parameter to `Chengdu` or `Xian` in [ST_ResNet.py]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_ResNet/ST_ResNet.py ) , and then run it.\n\n  ```bash\n   python ST_ResNet.py \n  ```\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/didi_trial.py) Run Code & Setting.\n\n* [DCRNN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/didi_trial.py ) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [didi_xian.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_xian.data.yml) , [didi_chengdu.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_chengdu.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    ```\n  \n  * TMeta-LSTM-GAL\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:12')\n    ```\n  \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    ```\n    \n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    ```\n  \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    ```\n    \n\n### Metro Passenger\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |  **Chongqing**  |  **Shanghai**  |\n  | :--------: | :-------------: | :------------: |\n  |     HM     |     `2-1-4`     |    `1-0-4`     |\n  |  XGBoost   |  `12-6-4-51-8`  | `11-10-4-31-7` |\n  |    GBRT    | `12-14-1-182-7` | `12-7-1-148-5` |\n\n  | 30 minutes | **Chongqing**  |  **Shanghai**  |\n  | :--------: | :------------: | :------------: |\n  |     HM     |    `1-0-4`     |    `1-1-3`     |\n  |  XGBoost   | `11-5-0-45-8`  | `12-6-1-206-3` |\n  |    GBRT    | `10-3-0-107-8` |  `7-4-1-58-7`  |\n\n  | 60 minutes |  **Chongqing**   | **Shanghai** |\n  | :--------: | :--------------: | :----------: |\n  |     HM     |     `0-1-4`      |   `0-0-4`    |\n  |  XGBoost   |  `9-14-2-200-5`  | `3-7-0-50-5` |\n  |    GBRT    | `12-10-4-200-5 ` | `9-5-1-66-6` |\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metro_trial.py ) Run Code & Setting.\n\n* [DCRNN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metro_trial.py) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [metro_chongqing.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_chongqing.data.yml) , [metro_shanghai.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_shanghai.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM \n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    ```\n    \n  * TMeta-LSTM-GAL\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:12')\n    ```\n  \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    ```\n  \n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    ```\n    \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n            '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    ```\n    \n\n### Electric Vehicle\n\n* HM & XGBoost & GBRT\n\n  | Beijing |  30 minutes   |   60 minutes    |\n  | :-----: | :-----------: | :-------------: |\n  |   HM    |    `2-0-0`    |     `2-0-2`     |\n  | XGBoost | `6-6-1-19-2`  |  `12-7-0-20-2`  |\n  |  GBRT   | `13-3-2-47-3` | `12-10-0-100-2` |\n\n* [ST_MGCN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/cs_trial.py ) Run Code & Setting.\n\n* [DCRNN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/cs_trial.py ) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [chargestation_beijing.data.yml]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/chargestation_beijing.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM \n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:2')\n    ```\n  \n  * TMeta-LSTM-GAL\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:2')\n    ```\n  \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n            ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n    ```\n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n            ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n    ```\n  \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n    ```\n\n### Traffic Speed\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |  **METR-LA**  | **PEMS-BAY**  |\n  | :--------: | :-----------: | :-----------: |\n  |     HM     |    `2-0-4`    |    `1-0-1`    |\n  |  XGBoost   | `11-1-2-25-3` | `12-4-2-21-4` |\n  |    GBRT    | `11-8-2-29-4` | `10-6-1-65-6` |\n\n  | 30 minutes |  **METR-LA**  |  **PEMS-BAY**  |\n  | :--------: | :-----------: | :------------: |\n  |     HM     |    `2-0-4`    |    `1-0-1`     |\n  |  XGBoost   | `6-6-0-25-3`  | `12-13-2-27-3` |\n  |    GBRT    | `10-0-0-27-3` | `12-6-2-90-7`  |\n\n  | 60 minutes |  **METR-LA**  | **PEMS-BAY**  |\n  | :--------: | :-----------: | :-----------: |\n  |     HM     |    `2-1-4`    |    `1-1-4`    |\n  |  XGBoost   | `2-2-0-25-3`  | `12-6-2-19-3` |\n  |    GBRT    | `4-5-1-19-4`  | `12-7-2-59-5` |\n\n* [METR-LA](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metr_trial.py)  and [PEMS-BAY](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/pems_trial.py)  ST_MGCN Run Code & Setting.\n\n* [METR-LA](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metr_trial.py) and [PEMS-BAY](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/pems_trial.py) DCRNN Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [metr_la.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metr_la.data.yml) , [pems_bay.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/pems_bay.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM \n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    ```\n\n  * TMeta-LSTM-GAL\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:12')\n    ```\n\n  * STMeta-V1\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    ```\n\n  * STMeta-V2\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    ```\n\n  * STMeta-V3\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    ```\n\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/md_file/installation.md.txt",
    "content": "## Installation\n\nUCTB is based on several well-known deep learning frameworks, including **PyTorch**, **TensorFlow**, and **MXNet**. If you have an Nvidia GPU installed on your computer, we highly recommend you install the GPU version of these frameworks.\n\nUCTB toolbox may not work successfully with the upgrade of some packages. We thus encourage you to use the specific version of packages to avoid unseen errors. ***To avoid potential conflict, we highly recommend you install UCTB vis Anaconda.***\n\n### Install via Anaconda\n\n**Step 1: Install Anaconda**\n\nYou can skip to step 2 if you already installed Anaconda.\n\nTo install Anaconda, please refer to this page <https://www.anaconda.com/download>.\n\n\n\n**Step 2: create UCTB environment**\n\nCreate the UCTB environment by the following command. You may need the [environment.yaml](https://github.com/uctb/UCTB/blob/master/environment.yaml) file.\n\n```bash\nconda env create -f environment.yaml\n```\n\nThen activate the UCTB environment and start to use it. 🎉🎉🎉\n\n```bash\nconda activate UCTB\n```\n\n\n\n### Check for Success\n\nIf you  successfully install UCTB, you may get the following output after importing UCTB. \n\n```\n(UCTB) XXX:~$ python\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n>>> import UCTB\nUsing TensorFlow backend.\n>>> \n```\n\n### High version GPU Framework support\n\n**Existing Problems**\n\nDue to changes in the design architecture of high-version GPUs, low-version CUDA is not compatible with high-version GPUs. As a result, Tensorflow 1.x is only compatible with low-version CUDA, leading to runtime failures on machines equipped with high-version GPUs. https://stackoverflow.com/questions/50622525/which-tensorflow-and-cuda-version-combinations-are-compatible \n\n**Solution**\n\nThanks to the [Nvidia TensorFlow](https://github.com/NVIDIA/tensorflow) project, which was created to support newer hardware and improve libraries for NVIDIA GPU users using TensorFlow 1.x, we can now install UCTB on machines with newer GPUs. You can follow the installation tutorial below to start enjoying UCTB.\n\n**Clone the project**\n\n```sh\n>>> git clone git@github.com:uctb/UCTB.git\n>>> cd UCTB\n```\n\n**Create Anaconda Environment**\n\n```sh\n>>> conda create -n UCTB python=3.8\n>>> conda activate UCTB\n```\n\n**Install Nvidia Tensorflow**\n\n```sh\n>>> pip install --user nvidia-pyindex\n>>> pip install --user nvidia-tensorflow[horovod]\n```\n\n**Install UCTB from Source**\n\n```sh\n>>> python build_install.py\n```\n\n\n\n### Q & A\n\n**Q: I fail to install PyTorch, TensorFlow, and MXNet, what is the version number of them?**\n\nA: We recommend you install PyTorch==1.1.0, TensorFlow==1.13.1, and MXNet==1.5.0 with cuda version 10.0. We here give the installation command:\n\n```bash\n# Install PyTorch\nconda install pytorch==1.1.0 torchvision==0.3.0 cudatoolkit=10.0 -c pytorch\n\n# Install TensorFlow\nconda install tensorflow-gpu==1.13.1\n\n# Install MXNet\npip install mxnet-cu100==1.5.0\n```\n\n\n\n**Q:  I'm using Windows OS, and my Anaconda reports that it cannot find the PyTorch 1.1.0 packages. How to install it?**\n\nA: You could install it by the following command.\n\n```bash\npip install torch==1.1.0 torchvision==0.3.0 -f https://download.pytorch.org/whl/cu100/torch_stable.html\n```\n\n\n\n**Q:  I fail to install UCTB via pip. How to install it ?**\n\nA: This situation may occur when your OS is Windows. You could install UCTB by its source code. First download UCTB's source code and your folder may look like this:\n\n```bash\nXXX/UCTB-master# ls\nbuild_install.py  dist  environment.yaml  __init__.py  QuickStarts  setup.py\nbuild.py          docs  Experiments       LICENSE      README.md    UCTB\n```\n\nthen build and install UCTB by the following command:\n\n```bash\npython build_install.py\n```\n\n<u>[Back To HomePage](../index.html)</u>"
  },
  {
    "path": "docs/sphinx/_build/_sources/md_file/introduction.md.txt",
    "content": "## Introduction\n\n**Urban Computing Tool Box** is a package providing [**urban datasets**](https://github.com/uctb/Urban-Dataset), [**spatial-temporal prediction models**](https://github.com/uctb/UCTB), and [**visualization tools**](https://github.com/uctb/visualization-tool-UCTB) for various urban computing tasks, such as traffic prediction, crowd flow prediction, ridesharing demand prediction, etc. \n\nUCTB is a flexible and open package. You can use the data we provided or use your data, and the data structure is well stated in the [**tutorial section**](https://uctb.github.io/UCTB/md_file/tutorial.html). \n\n### Urban Datasts\n\nUCTB also releases [a public dataset repository](https://github.com/uctb/Urban-Dataset) including the following applications:\n\n| **Application**  |        **City**        |     **Time Range**     | **Temporal Granularity** |                                                      **Dataset Link**                                                       |\n|:----------------:|:----------------------:|:----------------------:|:------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|\n|   Bike-sharing   |          NYC           | 2013.07.01-2017.09.30  |        5 minutes         |            [66.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip)             | \n|   Bike-sharing   |        Chicago         | 2013.07.01-2017.09.30  |        5 minutes         |          [30.2M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip)           | \n|   Bike-sharing   |           DC           | 2013.07.01-2017.09.30  |        5 minutes         |             [31.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip)             | \n| Pedestrian Count |       Melbourne        | 2021.01.01-2022.11.01  |        60 minutes        | [1.18M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip) |\n|  Vehicle Speed   |           LA           | 2012.03.01-2012.06.28  |        5 minutes         |            [11.8M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip)             |\n|  Vehicle Speed   |          BAY           | 2017.01.01-2017.07.01  |        5 minutes         |            [27.9M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip)            |\n|   Taxi Demand    |        Chicago         | 2013.01.01-2018.01.01  |        15 minutes        |          [6.1M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|       Bus        |          NYC           | 2022.02.01-2024.01.13  |         60 mins          |             [4.89M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip)             |\n|      Metro       |          NYC           | 2022.02.01-2023.12.21  |         60 mins          |           [11.3M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip)           |\n|   Traffic Flow   |         Luzern         | 2015.01.01-2016.01.01  |          3 mins          |            [21M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Flow/3_minutes/Flow_Luzern.zip)            |\n|   Ride-sharing   |  Chicago (community)   | 2013.01.01-2018.01.01  |         15 mins          |          [6.06](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|   Ride-sharing   | Chicago (census tract) | 2013.01.01-2018.01.01  |         15 mins          |    [10M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip)     |\n|   Ride-sharing   |          NYC           | 2009.01.01-2023.06.01  |          5 mins          |    \n\nWe provide [detailed documents](https://github.com/uctb/Urban-Dataset/blob/main/Tutorial/tutorial.ipynb) about how to build and how to use these datasets.\n\n### Predictive Tool\n\nCurrently, the package supports the following models: (This toolbox is constructed based on some open-source repos. We appreciate these awesome implements. [See more details](https://uctb.github.io/UCTB/md_file/static/current_supported_models.html)).\n\n| Model Name                                                   | Input Data Format | Spatial Modeling Technique | Graph Type                                                   | Temporal Modeling Technique | Temporal Knowledge     | Module                      |\n| ------------------------------------------------------------ | ----------------- | -------------------------- | ------------------------------------------------------------ | --------------------------- | ---------------------- | --------------------------- |\n| ARIMA                                                        | Both              | N/A                        | N/A                                                          | SARIMA                      | Closeness              | ``UCTB.model.ARIMA``        |\n| HM                                                           | Both              | N/A                        | N/A                                                          | N/A                         | Closeness              | ``UCTB.model.HM``           |\n| HMM                                                          | Both              | N/A                        | N/A                                                          | HMM                         | Closeness              | ``UCTB.model.HMM``          |\n| XGBoost                                                      | Both              | N/A                        | N/A                                                          | XGBoost                     | Closeness              | ``UCTB.model.XGBoost``      |\n| DeepST [[SIGSPATIAL 2016]](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf) | Grid              | CNN                        | N/A                                                          | CNN                         | Closeness,Period,Trend | ``UCTB.model.DeepST``       |\n| ST-ResNet [[AAAI 2017]](https://arxiv.org/pdf/1610.00081.pdf) | Grid              | CNN                        | N/A                                                          | CNN                         | Closeness,Period,Trend | ``UCTB.model.ST_ResNet``    |\n| DCRNN  [[ICLR 2018]](https://arxiv.org/pdf/1707.01926.pdf)   | Node              | GNN                        | **Prior**(Sensor Network)                                    | RNN                         | Closeness              | ``UCTB.model.DCRNN``        |\n| GeoMAN  [[IJCAI 2018]](https://www.ijcai.org/proceedings/2018/0476.pdf) | Node              | Attention                  | **Prior**(Sensor Networks)                                   | Attention+LSTM              | Closeness              | ``UCTB.model.GeoMAN``       |\n| STGCN  [[IJCAI 2018]](https://www.ijcai.org/proceedings/2018/0505.pdf) | Node              | GNN                        | **Prior**(Traffic Network)                                   | Gated CNN                   | Closeness              | ``UCTB.model.STGCN``        |\n| GraphWaveNet [[IJCAI 2019]](https://www.ijcai.org/proceedings/2019/0264.pdf) | Node              | GNN                        | **Adaptive**                                                 | TCN                         | Closeness              | ``UCTB.model.GraphWaveNet`` |\n| ASTGCN  [[AAAI 2019]](https://ojs.aaai.org/index.php/AAAI/article/view/3881) | Node              | GNN+Attention              | **Prior**(Traffic Network)                                   | Attention                   | Closeness,Period,Trend | ``UCTB.model.ASTGCN``       |\n| ST-MGCN   [[AAAI 2019]](https://ojs.aaai.org/index.php/AAAI/article/view/4247) | Node              | GNN                        | **Prior**(Neighborhood,Functional similarity,Transportation connectivity) | CGRNN                       | Closeness              | ``UCTB.model.ST_MGCN``      |\n| GMAN  [[AAAI 2020]](https://ojs.aaai.org/index.php/AAAI/article/view/5477/5333) | Node              | Attention                  | **Prior**(Road Network)                                      | Attention                   | Closeness              | ``UCTB.model.GMAN``         |\n| STSGCN  [[AAAI 2020]](https://ojs.aaai.org/index.php/AAAI/article/view/5438) | Node              | GNN+Attention              | **Prior**(Spatial Network)                                   | Attention                   | Closeness              | ``UCTB.model.STSGCN``       |\n| AGCRN [[NeurIPS 2020]](https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf) | Node              | GNN                        | **Adaptive**                                                 | RNN                         | Closeness              | ``UCTB.model.AGCRN``        |\n| STMeta [[TKDE 2021]](https://arxiv.org/abs/2009.09379)       | Node              | GNN                        | **Prior**(Proximity,Functionality,Interaction/Same-line)     | LSTM/RNN                    | Closeness,Period,Trend | ``UCTB.model.STMeta``       |\n\n### Visualization Tool\n\nThe Visualization tool integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis.\n\nWelcome to visit the [website](http://39.107.116.221/) for a trial! \n\n<u>[Back To HomePage](../index.html)</u>\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/md_file/predictive_tool.md.txt",
    "content": "# Predictive Tool\n\n## Currently Supported Models\n\n### AGCRN\n\nAGCRN (Adaptive Graph Convolutional Recurrent Network) is a deep nerual network for traffic prediction consisting of two adaptive module and recurrent networks.\n\n- Reference Paper:\n  - [Bai, L., Yao, L., Li, C., Wang, X., & Wang, C. (2020). Adaptive graph convolutional recurrent network for traffic forecasting.](https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf)\n- Reference Implementation:\n  - [Github repository (LeiBAI)](https://github.com/LeiBAI/AGCRN)\n\n###  ARIMA\n\nARIMA (Autoregressive Integrated Moving Average) is a widely used classical statistical model on time series prediction.\n\n- Reference Paper:\n\n  + [Williams, B. M., & Hoel, L. A. (2003). Modeling and forecasting vehicular traffic flow as a seasonal ARIMA process: Theoretical basis and empirical results](https://www3.nd.edu/~busiforc/handouts/ARIMA%20Engineering%20Article.pdf)\n- Reference Package: `pandas`, `statsmodels`\n\n### ASTGCN \n\nASTGCN (Attenion Based Spatial-temporal Graph Convolutional Networks) is a deep neural network for traffic flow forecasting. It models temporal-dependencies from three perspectives using attetion mechanism. And it models spatial-dependencies employing graph convolutions.\n\n- Reference Paper:\n  - [Guo, S., Lin, Y., Feng, N., Song, C., & Wan, H. (2019, July). Attention based spatial-temporal graph convolutional networks for traffic flow forecasting.](https://ojs.aaai.org/index.php/AAAI/article/view/3881)\n- Reference Implementation:\n  - [Github repository (guoshnBJTU)](https://github.com/guoshnBJTU/ASTGCN-r-pytorch)\n\n###  DCRNN\n\nDCRNN (Diffusion Convolutional Recurrent Neural Network) is a deep learning framework for traffic forecasting that incorporates both spatial and temporal dependency in the traffic flow. It captures the spatial dependency using bidirectional random walks on the graph, and the temporal dependency using the encoder-decoder architecture with scheduled sampling.\n\n- Reference Paper:\n\n  + [Li, Y., Yu, R., Shahabi, C., & Liu, Y. (2017). Diffusion convolutional recurrent neural network: Data-driven traffic forecasting](https://arxiv.org/abs/1707.01926)\n- Reference Implementation: \n  + [A TensorFlow implementation of Diffusion Convolutional Recurrent Neural Network (liyaguang)](https://github.com/liyaguang/DCRNN)\n\n###  DeepST\n\nDeepST (Deep learning-based prediction model for Spatial-Temporal data) is composed of three components: 1) temporal dependent instances: describing temporal closeness, period and seasonal trend; 2) convolutional neural networks: capturing near and far spatial dependencies; 3) early and late fusions: fusing similar and different domains' data.\n\n- Reference Paper:\n\n  + [Zhang, J., Zheng, Y., Qi, D., Li, R., & Yi, X. (2016, October). DNN-based prediction model for spatio-temporal data](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf)\n\n###  GeoMAN \n\nGeoMAN (Multi-level Attention Networks for Geo-sensory Time Series Prediction) consists of two major parts: 1) A multi-level attention mechanism (including both local and global  spatial attentions in encoder and temporal attention in decoder) to model the dynamic spatio-temporal  dependencies; 2) A general fusion module to incorporate the external factors from different domains (e.g.,  meteorology, time of day and land use).\n\n- Reference Paper:\n\n  + [Liang, Y., Ke, S., Zhang, J., Yi, X., & Zheng, Y. (2018, July). GeoMAN: Multi-level Attention Networks for Geo-sensory Time Series Prediction](https://www.ijcai.org/proceedings/2018/0476.pdf)\n- Reference Implementation:\n  + [An easy implement of GeoMAN using TensorFlow (yoshall & CastleLiang)](https://github.com/yoshall/GeoMAN)\n\n### GMAN\n\nGMAN (Graph Multi-Attention Network) is a deep nerual network for traffic prediction adopting encoder-decoder architecture. Both encode and decoder consist of multiple spatio-temporal attention blocks to model spatio-temporal dependencies.\n\n- Reference Paper:\n  - [Zheng, C., Fan, X., Wang, C., & Qi, J. (2020, April). Gman: A graph multi-attention network for traffic prediction.](https://ojs.aaai.org/index.php/AAAI/article/view/5477)\n- Reference Implementation:\n  - [implementation of Graph Multi-Attention Network](https://github.com/zhengchuanpan/GMAN)\n\n### GraphWaveNet\n\nGraphWaveNet is an end-to-end novel graph neural network. It captures spatial dependencies through a self-adptive adjacency matrix. And it captures temporal dependencies through convolutions.\n\n- Reference Paper:\n  - [Wu, Z., Pan, S., Long, G., Jiang, J., & Zhang, C. (2019). Graph wavenet for deep spatial-temporal graph modeling.](https://www.ijcai.org/proceedings/2019/0264.pdf)\n- Reference Implementation:\n  - [Github repository (nnzhan)](https://github.com/nnzhan/Graph-WaveNet)\n\n###  HM (Historical Mean)\n\nHM is a constant model and always forecasts the sample mean of the historical data.\n\n###  HMM (Hidden Markov Model)\n\nHidden Markov Model is a statistical Markov model in which the system being modeled is assumed to be a Markov process with hidden states. It is often used in temporal pattern recognition.\n\n- Reference Paper:\n\n  + [Chen, Z., Wen, J., & Geng, Y. (2016, November). Predicting future traffic using hidden markov models](https://ieeexplore.ieee.org/abstract/document/7785328)\n- Reference Package: `hmmlearn`\n\n### STGCN \n\nSTGCN (Spatio-temporal Graph Convolutional Networks) is a deep learning framework for traffic forecasting with complete convolutional structures.\n\n- Reference Paper:\n  - [Yu, B., Yin, H., & Zhu, Z. (2017). Spatio-temporal graph convolutional networks: A deep learning framework for traffic forecasting.](https://www.ijcai.org/proceedings/2018/0505.pdf)\n- Reference Implementation:\n  - [Github repository (VeritasYin)](https://github.com/VeritasYin/STGCN_IJCAI-18)\n\n### STMeta\n\nSTMeta is our prediction model, which requires extra graph information as input, and combines Graph Convolution LSTM and Attention mechanism.\n\n- Reference Package: `tensorflow`\n\n### ST-MGCN \n\nST-MGCN (Spatiotemporal Multi-graph Convolution Network) is a deep learning based model which encoded the non-Euclidean correlations among regions using multiple graphs and explicitly captured them using multi-graph convolution.\n\n- Reference Paper:\n\n  + [Geng, X., Li, Y., Wang, L., Zhang, L., Yang, Q., Ye, J., & Liu, Y. (2019). Spatiotemporal multi-graph convolution network for ride-hailing demand forecasting](https://ieeexplore.ieee.org/abstract/document/7785328)\n- Reference Implementation:\n  + [A PyTorch implementation of the ST-MGCN model  (shawnwang-tech)](https://github.com/shawnwang-tech/ST-MGCN-pytorch)\n\n### ST-ResNet\n\nST-ResNet is a deep-learning model with an end-to-end structure based on unique properties of spatio-temporal data making use of convolution and residual units.\n\n- Reference Paper:\n  - [Zhang, J., Zheng, Y., & Qi, D. (2017, February). Deep spatio-temporal residual networks for citywide crowd flows prediction](https://arxiv.org/pdf/1610.00081.pdf)\n- Reference Implementation:\n  - [Github repository (lucktroy)](https://github.com/lucktroy/DeepST/tree/master/scripts/papers/AAAI17)\n\n### STSGCN \n\nSTSGCN (Spatial-temporal Synchronous Graph Convolutional Networks) is a deep learning framework for spatial-temporal network data forecasting. It is able to capture spatial-temporal dependencies through a designed spatial-temporal synchronous modeling mechanism.\n\n- Reference Paper:\n  - [Song, C., Lin, Y., Guo, S., & Wan, H. (2020, April). Spatial-temporal synchronous graph convolutional networks: A new framework for spatial-temporal network data forecasting.](https://ojs.aaai.org/index.php/AAAI/article/view/5438)\n- Reference Implementation:\n  - [Github repository (Davidham3)](https://github.com/Davidham3/STSGCN)\n\n### XGBoost\n\nXGBoost is a gradient boosting machine learning algorithm widely used in flow prediction and other machine learning prediction areas.\n\n- Reference Paper:\n  - [Alajali, W., Zhou, W., Wen, S., & Wang, Y. (2018). Intersection Traffic Prediction Using Decision Tree Models](https://www.mdpi.com/2073-8994/10/9/386)\n- Reference Package: `xgboost`\n\n## Quick Start\n\n### Quick start with STMeta\n\n```python\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n# Config data loader\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', graph='Correlation',\n                                closeness_len=6, period_len=7, trend_len=4, normalize=True)\n\n# Build Graph\ngraph_obj = GraphGenerator(graph='Correlation', data_loader=data_loader)\n\n# Init model object\nSTMeta_Obj = STMeta(closeness_len=data_loader.closeness_len,\n                    period_len=data_loader.period_len,\n                    trend_len=data_loader.trend_len,\n                    num_node=data_loader.station_number,\n                    num_graph=graph_obj.LM.shape[0],\n                    external_dim=data_loader.external_dim)\n\n# Build tf-graph\nSTMeta_Obj.build()\n# Training\nSTMeta_Obj.fit(closeness_feature=data_loader.train_closeness,\n               period_feature=data_loader.train_period,\n               trend_feature=data_loader.train_trend,\n               laplace_matrix=graph_obj.LM,\n               target=data_loader.train_y,\n               external_feature=data_loader.train_ef,\n               sequence_length=data_loader.train_sequence_len)\n\n# Predict\nprediction = STMeta_Obj.predict(closeness_feature=data_loader.test_closeness,\n                                period_feature=data_loader.test_period,\n                                trend_feature=data_loader.test_trend,\n                                laplace_matrix=graph_obj.LM,\n                                target=data_loader.test_y,\n                                external_feature=data_loader.test_ef,\n                                output_names=['prediction'],\n                                sequence_length=data_loader.test_sequence_len)\n\n# Evaluate\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.min_max_denormal(prediction['prediction']),\n                                 target=data_loader.normalizer.min_max_denormal(data_loader.test_y)))\n```\n\n### Quick Start with HM\n\n```python\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import HM\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=1, period_len=1, trend_len=2,\n                                with_lm=False, normalize=False)\n\nhm_obj = HM(c=data_loader.closeness_len, p=data_loader.period_len, t=data_loader.trend_len)\n\nprediction = hm_obj.predict(closeness_feature=data_loader.test_closeness,\n                            period_feature=data_loader.test_period,\n                            trend_feature=data_loader.test_trend)\n\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))\n```\n\n### Quick Start with ARIMA\n\n```python\nimport numpy as np\n\nfrom UCTB.model import ARIMA\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=24, period_len=0, trend_len=0,\n                                with_lm=False, normalize=False)\n\ntest_prediction_collector = []\nfor i in range(data_loader.station_number):\n    try:\n        model_obj = ARIMA(time_sequence=data_loader.train_closeness[:, i, -1, 0],\n                          order=[6, 0, 1], seasonal_order=[0, 0, 0, 0])\n        test_prediction = model_obj.predict(time_sequences=data_loader.test_closeness[:, i, :, 0],\n                                            forecast_step=1)\n    except Exception as e:\n        print('Converge failed with error', e)\n        print('Using last as prediction')\n        test_prediction = data_loader.test_closeness[:, i, -1:, :]\n    test_prediction_collector.append(test_prediction)\n    print('Station', i, 'finished')\n\ntest_rmse = metric.rmse(np.concatenate(test_prediction_collector, axis=-2), data_loader.test_y)\n\nprint('test_rmse', test_rmse)\n```\n\n### Quick Start with HMM\n\n```python\nimport numpy as np\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import HMM\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC',\n                                closeness_len=12, period_len=0, trend_len=0,\n                                with_lm=False, normalize=False)\n\nprediction = []\nfor station_index in range(data_loader.station_number):\n    # train the hmm model\n    try:\n        hmm = HMM(num_components=8, n_iter=100)\n        hmm.fit(data_loader.train_closeness[:, station_index:station_index+1, -1, 0])\n        # predict\n        p = []\n        for time_index in range(data_loader.test_closeness.shape[0]):\n            p.append(hmm.predict(data_loader.test_closeness[time_index, station_index, :, :], length=1))\n    except Exception as e:\n        print('Failed at station', station_index, 'with error', e)\n        # using zero as prediction\n        p = [[[0]] for _ in range(data_loader.test_closeness.shape[0])]\n\n    prediction.append(np.array(p)[:, :, 0])\n    print('Node', station_index, 'finished')\n\nprediction = np.array(prediction).transpose([1, 0, 2])\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))\n```\n\n### Quick Start with XGBoost\n\n```python\nimport numpy as np\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import XGBoost\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=6, period_len=7, trend_len=4,\n                                with_lm=False, normalize=False)\n\nprediction_test = []\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = XGBoost(n_estimators=100, max_depth=3, objective='reg:squarederror')\n\n    model.fit(np.concatenate((data_loader.train_closeness[:, i, :, 0],\n                              data_loader.train_period[:, i, :, 0],\n                              data_loader.train_trend[:, i, :, 0],), axis=-1),\n              data_loader.train_y[:, i, 0])\n\n    p_test = model.predict(np.concatenate((data_loader.test_closeness[:, i, :, 0],\n                                           data_loader.test_period[:, i, :, 0],\n                                           data_loader.test_trend[:, i, :, 0],), axis=-1))\n\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\n\nprediction_test = np.concatenate(prediction_test, axis=-2)\n\nprint('Test RMSE', metric.rmse(prediction_test, data_loader.test_y))\n```\n\n## Tutorial\n\nThe general process of completing a spatiotemporal prediction task includes: loading dataset, defining model, training, testing, model evaluation.\n\n![tutorial](https://uctb.github.io/UCTB/sphinx/md_file/src/image/tutorial.png)\n\n### Load datasets from Urban_dataset\n\nTo help better accuse dataset, UCTB provides data loader APIs `UCTB.dataset.data_loader`, which can be used to preprocess data, including **data division**, **normalization**, and **extract temporal and spatial knowledge**.\n\nIn the following tutorial, we will illustrate how to use `UCTB.dataset.data_loader` APIs to inspect the speed dataset.\n\n```python\nfrom UCTB.dataset.data_loader import NodeTrafficLoader\n```\n\nWe use all(data_range='all') of speed data in METR_LA(Assume that scripts are put under root directory, METR_LA dataset is put under `./data` directory.). Firstly, let's initialize a NodeTrafficLoader object:\n\n```python\ndata_loader = NodeTrafficLoader(city='LA',\n                 data_range='all',\n                 train_data_length='all',\n                 test_ratio=0.1,\n                 closeness_len=6,\n                 period_len=7,\n                 trend_len=4,\n                 target_length=1,\n                 normalize=False,\n                 data_dir='data',\n                 MergeIndex=1,\n                 MergeWay=\"sum\",dataset='METR',remove=False)\n```\n\n\n\nNodeTrafficLoader is the base class for dataset extracting and processing. Input arguments appeared in constructor above will be explained.\n\n- data range selection\n`*data range = 'all'` means that we choose the whole data as our traffic_data to train, test, and predict.\n\n- data spliting(train set and test set spliting)\n\n`train_data length = 'all'` means that we exploit all of the traffic_data. `'train_test_ratio = 0.1` means we divide the dataset into train and test sets. And the train set to the test set is nine to one.\n\n- normalization\n\n`normalization = False` means that we normalized the dataset through min-max-normalization method. When we input False, we simply do not employ any preprocessing tricks on the dataset.\n\n- data merging\n\n`MergeIndex = 1, MergeWay = 'sum'` means that granularity of raw dataset will not be changed. If we try MergeIndex > 1, we can obtain combination of MergeIndex time slots of data in a way of 'sum' or 'average'.\n\n- multiple time series building(temporal knowledge exploiting)\n\n`closeness_len = 6, period_len=7, trend_len=4, target_length=1` means that we create 3 time series, using former consecutive closeness_len time slots of data as a unit, former every other daily_slots time slots of data as a unit(consisting of period_len piece of data), former every other daily_slots*7 time slots of data as a unit(consisting of trend_len piece of data) respectively.\n\n```python\nprint(data_loader.train_closeness.shape)\nprint(data_loader.train_period.shape)\nprint(data_loader.train_trend.shape)\nprint(data_loader.train_data.shape)\n```\n```\n(22780, 207, 6, 1)\n(22780, 207, 7, 1)\n(22780, 207, 4, 1)\n(30844, 207)\n```\nYou may probably note that the length of train_closeness is 13778 less than that of train_data. It's because we choose the shortest data length among the three series(train_trend) for alignment.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/data_reassemble.png\" style=\"zoom: 10%;\" />\n\nAbove is the visualization of a new time series's construction. In this situation, feature_stride = 3(means sampling interval), feature_step = 3(means how many times we sample).Other time series are just the same situation.\n\nThrough the process in the figure shown above, we can calculate the length of train_trend is $30844-12*24*7*4=22780$, which is the minimum among three time series.\n\n**Operations**\n\n- Denormalization/Normalization\n- Visualization\n- Temporal Knowledge Exploitation\n- Spatial knowledge Exploration\n- Access to raw data\n\n```python\nimport matplotlib.pyplot as plt\nfrom UCTB.preprocess.preprocessor import Normalizer\n\n# without normalization\n\ntarget_node = 5\nplt.plot(data_loader.traffic_data[:,5])\nplt.title('Raw')\nplt.show()\n\n# normalization\n\nnormalizer=Normalizer(data_loader.traffic_data)\nX_normalized = normalizer.min_max_normal(data_loader.traffic_data)\n\n# denormalization\n\nX_denormalized = normalizer.min_max_denormal(X_normalized)\n\nplt.plot(X_normalized[:,5])\nplt.title('Normalized')\nplt.show()\nplt.plot(X_denormalized[:,5])\nplt.title('Denormalized')\nplt.show()\n```\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Raw_data.png\" alt=\"Raw_data\" style=\"zoom:33%;\" /><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/normalized_data.png\" style=\"zoom:33%;\" /><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/denormalized_data.png\" style=\"zoom:33%;\" />\n\n```python\n# Nodes' location visualizations\ndata_loader.st_map()\n```\n\nVisualization result is as follows:\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/METR_LA.png\" alt=\"Node location of METR_LA\" style=\"zoom: 50%;\" />\n\n```python\n# data visualization\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nreal_denormed=data_loader.normalizer.min_max_denormal(data_loader.test_y)\nsns.heatmap(real_denormed[:,:,0], cmap='Reds', vmin = -1000, vmax = 4000)\nplt.ylabel(\"Time Slot\")\nplt.xlabel(\"Sensor Node\")\nplt.title(\"Visualization\")\nplt.show()\n```\n\n```python\n# Feature stitching\nX = data_loader.make_concat()\nprint('before concatenate')\nprint('closeness')\nprint(data_loader.train_closeness.shape)\nprint('period')\nprint(data_loader.train_period.shape)\nprint('trend')\nprint(data_loader.train_trend.shape)\nprint('After concatenate')\nprint(X.shape)\n```\n```\nbefore concatenate\ncloseness\n(22780, 207, 6, 1)\nperiod\n(22780, 207, 7, 1)\ntrend\n(22780, 207, 4, 1)\nAfter concatenate\n(22780, 207, 17, 1)\n```\n```python\n# access to raw data\nprint(data_loader.traffic_data[0,0])\n```\n\n```\n64.375\n```\n\n### Model definition, train, test and evaluation\n\nWe use XGBoost interface in UCTB as an example to define a model. Since there are total 207 stations in METR_LA dataset, we define 207 XGBoost models respectively. They are trained and tested in their own iteration related to stations. Finally, when we evaluate our model, we consider the prediction results as a whole and evaluate it against GroundTruth provided by `data_loader` using [RMSE](https://en.wikipedia.org/wiki/Root-mean-square_deviation) metric.\n\n```python\n\nfrom UCTB.evaluation import metric\nfrom UCTB.model import XGBoost\nimport UCTB.evaluation.metric as metric\nprediction_test = []\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = XGBoost(n_estimators=100, max_depth=3, objective='reg:squarederror')\n\n    model.fit(np.concatenate((data_loader.train_closeness[:, i, :, 0],\n                              data_loader.train_period[:, i, :, 0],\n                              data_loader.train_trend[:, i, :, 0],), axis=-1),\n              data_loader.train_y[:, i, 0])\n\n    p_test = model.predict(np.concatenate((data_loader.test_closeness[:, i, :, 0],\n                                           data_loader.test_period[:, i, :, 0],\n                                           data_loader.test_trend[:, i, :, 0],), axis=-1))\n\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\n\nprediction_test = np.concatenate(prediction_test, axis=-2)\n\ny_truth = data_loader.normalizer.inverse_transform(data_loader.test_y)\ny_pred = data_loader.normalizer.inverse_transform(prediction_test)\ny_truth = y_truth.reshape([-1,207])\ny_pred = y_pred.reshape([-1,207])\nprint('Test RMSE', metric.rmse(y_pred, y_truth))\nplt.title('XGBoost Result')\nplt.xlabel('Time Slot')\nplt.ylabel('Speed')\nplt.plot(y_pred[:12*24*7,target_node])\nplt.plot(y_truth[:12*24*7,target_node])\nplt.legend(['gt','pred'])\nplt.show()\n```\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/XGBoost_Result.png\" alt=\"XGBoost Result\" style=\"zoom:50%;\" />\n\n```\nTest RMSE 5.549781682961724\n```\n\n### Single vs. Multiple kinds of temporal knowledge\n\n#### Use temporal closeness feature in regression\n\nUCTB provides many classical and popular spatial-temporal predicting models. These models can be used to either predicting series for a single station or all stations. You can find the details in [``UCTB.model``](./static/current_supported_models.html).\n\nThe following example shows how to use a **XGBoost** model to handle a simple time series predicting a problem. We will try to predict the bike demands ``test_y`` of a fixed station ``target_node`` in New York City by checking back the historical demands in recent time slots ``train_closeness``.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom UCTB.model import XGBoost\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\ntarget_node = 233\n```\n\nWhen initializing the loader, we use past ``12`` time slots (timesteps) of closeness as input, ``1`` timestep in the next as output and set the timesteps of other features ``period_len``, ``period_len`` to zero. \n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=12, period_len=0, trend_len=0,\n                                target_length=1, test_ratio=0.2, \n                                normalize=False, with_lm=False, with_tpe=False)\n```\n\nThe well-loaded data contain all ``717`` stations' data. Therefore it is needed to specify the target station by ``target_station``.\n\n```python\nprint(data_loader.train_closeness.shape)\nprint(data_loader.test_closeness.shape)\nprint(data_loader.test_y.shape)\n```\n\n```python\n(2967, 717, 12, 1)\n(745, 717, 12, 1)\n(745, 717, 1)\n```\n\n\n```python\ntrain_x, test_x = data_loader.train_closeness[:, target_node, :, 0], data_loader.test_closeness[:, target_node, :, 0]\ntrain_y = data_loader.train_y[:, target_node,0]\ntest_y = data_loader.test_y[:, target_node, 0]\n```\n\nInspect the shape of data. Here are the all we need for one-station prediction.\n\n\n```python\nprint(train_x.shape)\nprint(train_y.shape)\nprint(test_x.shape)\nprint(test_y.shape)\n```\n\n    (2967, 12)\n    (2967,)\n    (745, 12)\n    (745,)\n\nBuild the XGBoost model.\n\n```python\nmodel = XGBoost(n_estimators=100, max_depth=3, objective='reg:linear')\n```\n\nNow, we can fit the model with the train dataset and make predictions on the test dataset.\n\n```python\nmodel.fit(x=train_x)\npredictions = model.predict(test_x)\n```\n\nWe can evaluate the performance of the model by build-in ``UCTB.evaluation`` APIs.\n\n```python\ntest_rmse = metric.rmse(predictions, test_y)\nprint(test_rmse)\n```\n\n    3.6033132\n\n#### Make full use of closeness, period, and trend features \n\nIn this case, let's take more temporal knowledge related to ``target_node`` into account. We will concatenate factors including ``closeness``, ``period``, and ``trend``, and use **XGBoost** as the predicting model.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom UCTB.model import XGBoost\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\ntarget_node = 233\n\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=6, period_len=7, trend_len=4,\n                                target_length=1, test_ratio=0.2, \n                                normalize=False, with_lm=False, with_tpe=False)\n\ntrain_closeness = data_loader.train_closeness[:, target_node, :, 0]\ntrain_period = data_loader.train_period[:, target_nodze, :, 0]\ntrain_trend = data_loader.train_trend[:, target_node, :, 0]\ntrain_y = data_loader.train_y[:, target_node, 0]\n\ntest_closeness = data_loader.test_closeness[:, target_node, :, 0]\ntest_period = data_loader.test_period[:, target_node, :, 0]\ntest_trend = data_loader.test_trend[:, target_node, :, 0]\ntest_y = data_loader.test_y[:, target_node, 0]\n\ntrain_X = np.concatenate([train_closeness, train_period, train_trend], axis=-1)\ntest_X = np.concatenate([test_closeness, test_period, test_trend], axis=-1)\n\nprint(train_X.shape)\nprint(train_y.shape)\nprint(test_X.shape)\nprint(test_y.shape)\n\nmodel = XGBoost(n_estimators=100, max_depth=3, objective='reg:linear')\nmodel.fit(train_X, train_y)\npredictions = model.predict(test_X)\nprint('Test RMSE', metric.rmse(predictions, test_y))\n```\n\n    (2307, 17)\n    (2307,)\n    (745, 17)\n    (745,)\n    Test RMSE 3.3267457\n## Advanced Features\n\n### Build your own model using UCTB\n\nUCTB provides extendable APIs to build your own model. Currently, it can support the running of all the ``1.x`` version of **Tensorflow-based** models. In the following tutorial, we will show you how to takes the least efforts to implement a UCTB model.\n\nCommonly, a new model needs to inherit ``BaseModel`` to acquire the features provided by UCTB, such as batch division, early stopping, etc. The necessary components for a subclass of ``BaseModel`` include:\n\n- ``self.__init__()``. Define the model's parameters related to the architecture. You should call the super class's constructor at first.\n- ``self.build()``. Build the architecture here. You should construct the graph at the beginning of this function and call the super class's ``build()`` function at the end.\n- ``self._input``. The ``dict`` used to record the acceptable inputs of the model, whose keys are the parameter names in ``model.fit()`` and ``model.predict()`` and values are the name of related tensors.\n- ``self._output``. The ``dict`` used to record the outputs of the model. You should fill the required keys ``prediction`` and ``loss`` with the names of tensors in your case.\n- ``self._op``. The ``dict`` used to define all the operations for the model. Basic usage for it is to record the **training operation**, for example, the minimizing loss operation of an optimizer. Use key ``train_op`` to record it.\n\nFor more examples, you can refer to the implementations of build-in models in [``UCTB.model``](../UCTB.model.html#uctb-model-package).\n\n\n```python\nfrom UCTB.model_unit import BaseModel\n\nclass MyModel(BaseModel):\n    def __init__(self,\n                 \n                 code_version='0',\n                 model_dir='my_model',\n                 gpu_device='0',\n                ):\n        super(MyModel, self).__init__(code_version=code_version, \n                                      model_dir=model_dir, gpu_device=gpu_device)\n        ...\n        \n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            ...\n            self._input['inputs'] = inputs.name\n            self._input['targets'] = targets.name\n            \n            ...\n            self._output['prediction'] = predictions.name\n            self._output['loss'] = loss.name\n            self._op['train_op'] = train_op.name\n            \n        super(MyModel, self).build(init_vars=init_vars, max_to_keep=5) \n```\n\nNext, in a concrete case, we will realize a **Long short-term memory (LSTM)** model to make the all-station prediction that accepts time series of `717` stations and predict the future of them as a whole. \n\nFor the mechanism of LSTM, you can refer to \n[Gers, F. A., Schmidhuber, J., & Cummins, F. (1999). Learning to forget: Continual prediction with LSTM](https://www.researchgate.net/profile/Felix_Gers/publication/12292425_Learning_to_Forget_Continual_Prediction_with_LSTM/links/5759414608ae9a9c954e84c5/Learning-to-Forget-Continual-Prediction-with-LSTM.pdf).\n\n\n```python\nimport numpy as np\nimport tensorflow as tf\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model_unit import BaseModel\nfrom UCTB.preprocess import SplitData\nfrom UCTB.evaluation import metric\n```\n\n\n```python\nclass LSTM(BaseModel):\n    def __init__(self,\n                 num_stations, \n                 num_layers, \n                 num_units, \n                 input_steps, \n                 input_dim,\n                 output_steps,\n                 output_dim,\n                 code_version='0',\n                 model_dir='my_lstm',\n                 gpu_device='0'):\n        super(LSTM, self).__init__(code_version=code_version, \n                                   model_dir=model_dir, gpu_device=gpu_device)\n        self.num_stations = num_stations\n        self.num_layers = num_layers\n        self.num_units = num_units\n        self.input_steps = input_steps\n        self.input_dim = input_dim\n        self.output_steps = output_steps\n        self.output_dim = output_dim\n        \n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            inputs = tf.placeholder(tf.float32, shape=(None, self.num_stations, \n                                                       self.input_steps, self.input_dim))\n            targets = tf.placeholder(tf.float32, shape=(None, self.num_stations,\n                                                       self.output_steps, self.output_dim))\n            # record the inputs of the model\n            self._input['inputs'] = inputs.name\n            self._input['targets'] = targets.name\n\n            inputs = tf.reshape(inputs, (-1, self.input_steps, self.num_stations*self.input_dim))\n            \n            def get_a_cell(num_units):\n                lstm = tf.nn.rnn_cell.BasicLSTMCell(num_units, state_is_tuple=True)\n                return lstm\n            \n            stacked_cells = tf.contrib.rnn.MultiRNNCell([get_a_cell(self.num_units) for _ in range(self.num_layers)], state_is_tuple=True)\n            outputs, final_state = tf.nn.dynamic_rnn(stacked_cells, inputs, dtype=tf.float32)\n            \n            stacked_outputs = tf.reshape(outputs, shape=(-1, self.num_units*self.input_steps))\n            predictions = tf.layers.dense(stacked_outputs, self.output_steps*self.num_stations*self.output_dim)\n            predictions = tf.reshape(predictions, shape=(-1, self.num_stations, self.output_steps, self.output_dim))\n            \n            loss = tf.sqrt(tf.reduce_mean(tf.square(predictions - targets)))\n            train_op = tf.train.AdamOptimizer().minimize(loss)\n            \n            # record the outputs and the operation of the model\n            self._output['prediction'] = predictions.name\n            self._output['loss'] = loss.name\n            self._op['train_op'] = train_op.name\n        \n        # must call super class' function to build \n        super(LSTM, self).build(init_vars=init_vars, max_to_keep=5) \n```\n\nLoad the dataset by loader and transform them into the formats your model accepts. If the loader APIs are not filled your demands, you can inherit loader and wrapper it according to your desires (see [Quickstart](./quickstart.html) for more details).\n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=6, period_len=0, trend_len=0,\n                                target_length=1, test_ratio=0.2, \n                                normalize=True, with_lm=False, with_tpe=False)\ntrain_y = np.expand_dims(data_loader.train_y, axis=-1)\ntest_y = np.expand_dims(data_loader.test_y, axis=-1)\n```\n\n\n```python\nmodel = LSTM(num_stations=data_loader.station_number, \n             num_layers=2,\n             num_units=512, \n             input_steps=6, \n             input_dim=1, \n             output_steps=1, \n             output_dim=1)\n```\n\n\n```python\nmodel.build()\nprint(model.trainable_vars)  # count the trainble parameters\n```\n\n    6821581\n\nUse your model to training and predicting. ``model.fit()`` method presets lots of useful functions, such as batch division and early stopping. Check them in [``UCTB.model_unit.BaseModel.BaseModel.fit``](../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.fit).\n\n\n```python\nmodel.fit(inputs=data_loader.train_closeness,\n          targets=train_y,\n          max_epoch=10,\n          batch_size=64,\n          sequence_length=data_loader.train_sequence_len,\n          validate_ratio=0.1)\n```\n\n    No model found, start training\n    Running Operation ('train_op',)\n    Epoch 0: train_loss 0.016053785 val_loss 0.01606118\n    Epoch 1: train_loss 0.015499311 val_loss 0.015820855\n    Epoch 2: train_loss 0.015298592 val_loss 0.015657894\n    Epoch 3: train_loss 0.015163456 val_loss 0.015559187\n    Epoch 4: train_loss 0.015066812 val_loss 0.015342651\n    Epoch 5: train_loss 0.015016247 val_loss 0.015287879\n    Epoch 6: train_loss 0.014899823 val_loss 0.015249459\n    Epoch 7: train_loss 0.014773054 val_loss 0.015098239\n    Epoch 8: train_loss 0.014655286 val_loss 0.015097916\n    Epoch 9: train_loss 0.014558283 val_loss 0.015108417\n\n```python\npredictions = model.predict(inputs=data_loader.test_closeness, \n                            sequence_length=data_loader.test_sequence_len)\n```\n\nReverse the normalization by ``data_loader`` and evaluate the results:\n\n\n```python\npredictions = data_loader.normalizer.inverse_transform(predictions['prediction'])\ntargets = data_loader.normalizer.inverse_transform(test_y)\nprint('Test result', metric.rmse(prediction=predictions, target=targets))\n```\n\n    Test result 2.9765626570592545\n\nSince we only use a short period of the dataset (``data_range=0.1``) in this toy example, the result looks good compared with the [experiment](./all_results.html#results-on-bike). You can also take a try to test the completed dataset on your model. \n\n### Build your own graph with STMeta\n\nNext, we will use the Top-K graph as an example to illustrate how to build customized graphs in UCTB. All of the code in this section can be found [here](https://anonymous.4open.science/r/561305b5-e65e-46c6-9371-ae76b85109ee/Experiments/CustomizedDemo/).\n\n**Top-K graph**\n\nFirst of all, the customized graphs used in this section is called Top-K graph. We construct the corresponding adjacent graph by marking the point pair that consist of each point and its nearest K points as 1, and the others are marked as 0. Then, we use the adjacent graph to generate the laplacian matrix for input. The hyperparameter K is designed via ad-hoc heuristics. In this demonstration, we chose 23 as the value of K.\n\n**Realize TopK graph analysis module**\n\nTo adopt customized graphs (***e.g.,*** Top-K) in UCTB, you should first build your own analysis class by inheriting `UCTB.preprocess.GraphGenerator class`.\n\nIt is worth noting that the ultimate goal is to generate the member variables: `self.LM` and `self.AM`, which is the input matrix of the graph. In this phase, we need to make the corresponding analytical implementation according to the type of the custom graph passed in.\n\n ```python\n# \"UCTB/preprocess/topKGraph.py\"\nimport heapq\nimport numpy as np\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n\n# Define the class: topKGraph\nclass topKGraph(GraphGenerator):  # Init NodeTrafficLoader\n\n    def __init__(self,**kwargs):\n\n        super(topKGraph, self).__init__(**kwargs)\n        \n        for graph_name in kwargs['graph'].split('-'):\n\n# As the basic graph is implemented in GraphGenerator, you only need to implement your own graph function instead of the existing one.\n            if graph_name.lower() == 'topk':\n                lat_lng_list = np.array([[float(e1) for e1 in e[2:4]]\n                                         for e in self.dataset.node_station_info])\n                # Handling\n                AM = self.neighbour_adjacent(lat_lng_list[self.traffic_data_index],\n                                        threshold=int(kwargs['threshold_neighbour']))\n                LM = self.adjacent_to_laplacian(AM)\n\n                if self.AM.shape[0] == 0:  # Make AM\n                    self.AM = np.array([AM], dtype=np.float32)\n                else:\n                    self.AM = np.vstack((self.AM, (AM[np.newaxis, :])))\n\n                if self.LM.shape[0] == 0:  # Make LM\n                    self.LM = np.array([LM], dtype=np.float32)\n                else:\n                    self.LM = np.vstack((self.LM, (LM[np.newaxis, :])))\n\n# Implement the details of building the Top-K graph.\n    def neighbour_adjacent(self, lat_lng_list, threshold):\n        adjacent_matrix = np.zeros([len(lat_lng_list), len(lat_lng_list)])\n        for i in range(len(lat_lng_list)):\n            for j in range(len(lat_lng_list)):\n                adjacent_matrix[i][j] = self.haversine(\n                    lat_lng_list[i][0], lat_lng_list[i][1], lat_lng_list[j][0], lat_lng_list[j][1])\n        dis_matrix = adjacent_matrix.astype(np.float32)\n\n        for i in range(len(dis_matrix)):\n            ind = heapq.nlargest(threshold, range(len(dis_matrix[i])), dis_matrix[i].take)\n            dis_matrix[i] = np.array([0 for _ in range(len(dis_matrix[i]))])\n            dis_matrix[i][ind] = 1\n        adjacent_matrix = (adjacent_matrix == 1).astype(np.float32)\n        return adjacent_matrix\n ```\n\n**Redefine the call statement of the above class**\n\n```python\n# \"UCTB/Experiments/CustomizedDemo/STMeta_Obj_topk.py\"\n\n# Import the Class: topKGraph\nfrom topKGraph import topKGraph\n# Call topKGraph to initialize and generate AM and LM\ngraphBuilder = topKGraph(graph=args['graph'],\n                         data_loader=data_loader,\n                         threshold_distance=args['threshold_distance'],\n                         threshold_correlation=args['threshold_correlation'],\n                         threshold_interaction=args['threshold_interaction'],\n                         threshold_neighbour=args['threshold_neighbour'])\n# ......\n```\n\n**Modify the function call location**\n\nAdd the new graph name when fitting model and then execute it for experiments. [code](https://github.com/uctb/UCTB/blob/master/Experiments/CustomizedDemo/Runner_topk.py)\n\n```python\nos.system('python STMeta_Obj_topk.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line-TopK,MergeIndex:12')\n```\n\nWe conduct experiments on `Metro_Shanghai` dataset and use the [STMeta_V1](https://uctb.github.io/UCTB/md_file/all_results.html#stmeta-version) to model both \"Distance-Correlation-Line\" graph and \"Distance-Correlation-Line-TopK\" and the results are following:\n\n| **Metro: Shanghai** |             Graph              | Test-RMSE |\n| :-----------------: | :----------------------------: | :-------: |\n|      STMeta_V1      |   Distance-Correlation-Line    |  153.17   |\n|      STMeta_V1      | Distance-Correlation-Line-TopK |  140.82   |\n\nThe results show that the performance of STMeta_V1 with the graph \"Distance-Correlation-Line-TopK\" is better than \"Distance-Correlation-Line\" model and the RMSE is reduced by about 12.4%, which validates the effectiveness of the topk graph for spatiotemporal modeling STMeta algorithm.\n\n------\n\n<u>[Back To HomePage](../index.html)</u>\n\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/md_file/src/image/README.md.txt",
    "content": "Image resources\n\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/md_file/static/stable_test.md.txt",
    "content": "# Stable Test Records\r\n\r\n## DiDi Chengdu\r\n\r\n#### Parameters for building graph\r\n\r\n| Notation |          explanation           | value |\r\n| :------: | :----------------------------: | :---: |\r\n|    TD    |  threshold of distance graph   | 7500m |\r\n|    TI    | threshold of interaction graph |  30   |\r\n|    TC    | threshold of correlation graph | 0.65  |\r\n\r\n#### Parameters for building model\r\n\r\n```json\r\n{\r\n    \"L\": 1,\r\n    \"PT\": 7,\r\n    \"lr\": 5e-05,\r\n    \"TT\": 4,\r\n    \"DenseUnits\": 32,\r\n    \"GALUnits\": 64,\r\n    \"LSTMUnits\": 64,\r\n    \"ESlength\": 500,\r\n    \"patience\": 0.1,\r\n    \"Normalize\": \"True\",\r\n    \"TI\": 30.0,\r\n    \"CT\": 6,\r\n    \"K\": 1,\r\n    \"GALHeads\": 2,\r\n    \"Graph\": \"Distance-Interaction-Correlation\",\r\n    \"GLL\": 1\r\n}\r\n```\r\n\r\n|   实验编号   |   模型版本含义   |         Test-RMSE值          | Test-MAPE |\r\n| :----------: | :--------------: | :--------------------------: | :-------: |\r\n|      1       | STMeta-V2 |           6.98410            |  0.35470  |\r\n|      2       | STMeta-V2 |           7.06971            |  0.36585  |\r\n|      3       | STMeta-V2 |           7.00403            |  0.34867  |\r\n|      4       | STMeta-V2 |           7.04557            |  0.34797  |\r\n|      5       | STMeta-V2 |           7.05717            |  0.36398  |\r\n|      6       | STMeta-V2 |           6.97287            |  0.34735  |\r\n|      7       | STMeta-V2 |           7.03885            |  0.35656  |\r\n|      8       | STMeta-V2 |           7.09894            |  0.36024  |\r\n|      9       | STMeta-V2 |           7.02147            |  0.33930  |\r\n| 均值、标准差 |                  | 均值 7.03252，标准差 0.03865 |           |\r\n|   平均耗时   |                  |          0.5h~1.5h           |           |\r\n\r\n## DiDi Xian\r\n\r\n```json\r\n{\r\n    \"TrainDays\": \"All\",\r\n    \"DenseUnits\": 32,\r\n    \"GALUnits\": 64,\r\n    \"Graph\": \"Distance-Interaction-Correlation\",\r\n    \"CT\": 6,\r\n    \"Train\": \"False\",\r\n    \"Dataset\": \"DiDi\",\r\n    \"GLL\": 1,\r\n    \"TD\": 7500.0,\r\n    \"GALHeads\": 2,\r\n    \"patience\": 0.1,\r\n    \"Epoch\": 10000,\r\n    \"CodeVersion\": \"ST0\",\r\n    \"TT\": 4,\r\n    \"TC\": 0.65,\r\n    \"Device\": \"1\",\r\n    \"L\": 1,\r\n    \"PT\": 7,\r\n    \"ESlength\": 500,\r\n    \"LSTMUnits\": 64,\r\n    \"TI\": 30.0,\r\n    \"Normalize\": \"True\",\r\n    \"City\": \"Xian\",\r\n    \"lr\": 5e-05,\r\n    \"DataRange\": \"All\",\r\n    \"BatchSize\": 128,\r\n    \"K\": 1,\r\n    \"Group\": \"Xian\"\r\n}\r\n```\r\n\r\nSTMeta-V2 多次实验结果，每次实验耗时 0.5h~1.5h\r\n\r\n| 实验编号 | Test-RMSE | Test-MAPE |\r\n| :------: | :-------: | :-------: |\r\n|    1     |  5.80502  |  0.36022  |\r\n|    2     |  5.88970  |  0.35590  |\r\n|    3     |  6.00412  |  0.45126  |\r\n|    4     |  5.93798  |  0.37956  |\r\n|    5     |  6.01064  |  0.39242  |\r\n|    6     |  5.89309  |  0.40803  |\r\n|    7     |  5.84786  |  0.35915  |\r\n|    8     |  5.88188  |  0.36777  |\r\n|    9     |  5.97407  |  0.42393  |\r\n|    10    |  5.80497  |  0.37014  |\r\n\r\n最终结果：Test-RMSE 均值 5.90493，标准差 0.07142\r\n\r\nMetro Shanghai\r\n\r\n```json\r\n{\r\n    \"TrainDays\": \"All\",\r\n    \"patience\": 0.1,\r\n    \"Train\": \"False\",\r\n    \"TT\": 4,\r\n    \"City\": \"ShanghaiV1\",\r\n    \"ESlength\": 500,\r\n    \"K\": 1,\r\n    \"GLL\": 1,\r\n    \"LSTMUnits\": 64,\r\n    \"Normalize\": \"True\",\r\n    \"PT\": 7,\r\n    \"Epoch\": 10000,\r\n    \"GALUnits\": 64,\r\n    \"TI\": 100.0,\r\n    \"lr\": 2e-05,\r\n    \"Dataset\": \"Metro\",\r\n    \"DenseUnits\": 32,\r\n    \"L\": 1,\r\n    \"Group\": \"Shanghai\",\r\n    \"Graph\": \"Distance-line-Correlation\",\r\n    \"DataRange\": \"All\",\r\n    \"GALHeads\": 2,\r\n    \"CodeVersion\": \"ST_Sim_0\",\r\n    \"CT\": 6,\r\n    \"TD\": 5000.0,\r\n    \"TC\": 0.7,\r\n    \"BatchSize\": 128,\r\n    \"Device\": \"1\"\r\n}\r\n```\r\n\r\nSTMeta-V2 多次实验结果，每次实验耗时 6.5h~7.5h\r\n\r\n| 实验编号 | Test-RMSE | Test-MAPE |\r\n| :------: | :-------: | :-------: |\r\n|    1     | 148.88104 |  0.13178  |\r\n|    2     | 149.58350 |  0.14325  |\r\n|    3     | 168.16162 |  0.14498  |\r\n|    4     | 155.88750 |  0.19575  |\r\n|    5     | 155.09171 |  0.18060  |\r\n|    6     | 166.13303 |  0.18040  |\r\n|    7     | 157.08799 |  0.15245  |\r\n\r\n最终结果：Test-RMSE 均值 157.26091，标准差 6.90058\r\n\r\n## ChargeStation Beijing\r\n\r\n```json\r\n{\r\n    \"GALUnits\": 64,\r\n    \"TD\": 1000.0,\r\n    \"TI\": 500.0,\r\n    \"K\": 1,\r\n    \"Train\": \"False\",\r\n    \"CT\": 6,\r\n    \"patience\": 0.1,\r\n    \"ESlength\": 200,\r\n    \"Graph\": \"Distance-Correlation\",\r\n    \"Normalize\": \"True\",\r\n    \"lr\": 2e-05,\r\n    \"Device\": \"0\",\r\n    \"BatchSize\": 128,\r\n    \"LSTMUnits\": 64,\r\n    \"City\": \"Beijing\",\r\n    \"TrainDays\": \"All\",\r\n    \"CodeVersion\": \"ST_Sim1_0\",\r\n    \"TT\": 4,\r\n    \"GALHeads\": 2,\r\n    \"DenseUnits\": 32,\r\n    \"PT\": 7,\r\n    \"Group\": \"Beijing\",\r\n    \"L\": 1,\r\n    \"DataRange\": \"All\",\r\n    \"TC\": 0.1,\r\n    \"Epoch\": 10000,\r\n    \"Dataset\": \"ChargeStation\",\r\n    \"GLL\": 1\r\n}\r\n```\r\n\r\nSTMeta-V2 多次实验结果 (暂时只跑了4次)，每次实验耗时约 10h\r\n\r\n| 实验编号 | Test-RMSE | Test-MAPE |\r\n| :------: | :-------: | :-------: |\r\n|    1     |  0.80954  |  0.22925  |\r\n|    2     |  0.82956  |  0.23242  |\r\n|    3     |  0.82393  |  0.22467  |\r\n|    4     |  0.81360  |  0.22932  |\r\n\r\n最终结果：Test-RMSE 均值 0.81915，标准差 0.0079745\r\n\r\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/md_file/static/transfer_record.md.txt",
    "content": "## Check-In与POI数据处理方法\n\n#### 数据详情\n\n1. 时间范围：Apr 2012 ~ Sept 2013\n\n2. 三个城市的POI数量与check-in数量\n\n   |  城市   | POI数量(计算城市中心为原点、半径为50km的POI数量) | 日均check-in数量(粗略计算所有站点附近1km的checkin数量总和) |\n   | :-----: | :----------------------------------------------: | :--------------------------------------------------------: |\n   |   NYC   |                      71310                       |                  工作日11707，节假日11358                  |\n   | Chicago |                      21949                       |                   工作日2549，节假日2692                   |\n   |   DC    |                      21087                       |                   工作日6049，节假日5450                   |\n\n#### Check-In 特征计算方法\n\n计算 2013-07-15 到 2013-09-15 之间，各个自行车站点附近1km的checkin总数量，按照工作日和节假日分开，即每个站点的特征维度为48，分别为工作日、节假日的24小时checkin\n\n#### POI特征计算方法\n\n一共有428种POI，每个站点统计附近1km出现的POI类型，即每个站点有428维特征\n\n#### 特征相似度方法\n\nCosine Similarity\n\n## 使用Check-In数据进行相似站点的匹配\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|dc|nyc|0.1|1天|5.35244|**5.15155**|8.97297|\n|dc|nyc|0.1|3天|5.35244|**4.83186**|5.60889|\n|dc|nyc|0.1|5天|5.35244|**4.79484**|4.86073|\n|dc|nyc|0.1|7天|5.35244|**4.83927**|5.09481|\n|dc|chicago|0.1|1天|**3.65903**|3.67704|35.02312|\n|dc|chicago|0.1|3天|3.65903|**3.38682**|4.10283|\n|dc|chicago|0.1|5天|3.65903|**3.39081**|3.44701|\n|dc|chicago|0.1|7天|3.65903|**3.16186**|3.36458|\n|chicago|nyc|0.1|1天|7.48254|**6.19588**|8.28328|\n|chicago|nyc|0.1|3天|7.48254|**5.57436**|5.89025|\n|chicago|nyc|0.1|5天|7.48254|**5.54711**|5.64965|\n|chicago|nyc|0.1|7天|7.48254|**5.26407**|6.34057|\n|chicago|dc|0.1|1天|4.32390|**3.87629**|5.78612|\n|chicago|dc|0.1|3天|**4.32390**|4.99620|4.85723|\n|chicago|dc|0.1|5天|4.32390|**3.26380**|3.38408|\n|chicago|dc|0.1|7天|4.32390|**3.15168**|3.27858|\n|nyc|chicago|0.1|1天|5.17356|**4.43069**|12.75022|\n|nyc|chicago|0.1|3天|5.17356|**3.94628**|4.34232|\n|nyc|chicago|0.1|5天|5.17356|**3.93868**|4.52421|\n|nyc|chicago|0.1|7天|5.17356|3.46738|**3.44230**|\n|nyc|dc|0.1|1天|4.11176|**3.58924**|4.46261|\n|nyc|dc|0.1|3天|4.11176|**3.29204**|4.51947|\n|nyc|dc|0.1|5天|4.11176|**3.22782**|3.44588|\n|nyc|dc|0.1|7天|4.11176|**3.09117**|3.17292|\n\n## 使用POI信息进行相似站点匹配\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|dc|nyc|0.1|1天|5.35244|**5.15155**|7.74238|\n|dc|nyc|0.1|3天|5.35244|**4.83186**|5.22502|\n|dc|nyc|0.1|5天|5.35244|**4.79484**|5.14237|\n|dc|nyc|0.1|7天|5.35244|**4.83927**|5.11173|\n|dc|chicago|0.1|1天|**3.65903**|3.67704|42.10733|\n|dc|chicago|0.1|3天|3.65903|**3.38682**|4.01524|\n|dc|chicago|0.1|5天|3.65903|**3.39081**|3.80654|\n|dc|chicago|0.1|7天|3.65903|**3.16186**|3.40228|\n|chicago|nyc|0.1|1天|7.48254|**6.19588**|9.68558|\n|chicago|nyc|0.1|3天|7.48254|**5.57436**|6.06141|\n|chicago|nyc|0.1|5天|7.48254|**5.54711**|5.64207|\n|chicago|nyc|0.1|7天|7.48254|**5.26407**|5.95202|\n|chicago|dc|0.1|1天|4.32390|**3.87629**|7.71124|\n|chicago|dc|0.1|3天|**4.32390**|4.99620|5.20308|\n|chicago|dc|0.1|5天|4.32390|**3.26380**|3.41202|\n|chicago|dc|0.1|7天|4.32390|**3.15168**|3.36520|\n|nyc|chicago|0.1|1天|5.17356|**4.43069**|8.70660|\n|nyc|chicago|0.1|3天|5.17356|**3.94628**|4.68907|\n|nyc|chicago|0.1|5天|5.17356|**3.93868**|4.71885|\n|nyc|chicago|0.1|7天|5.17356|**3.46738**|3.54126|\n|nyc|dc|0.1|1天|4.11176|**3.58924**|4.54878|\n|nyc|dc|0.1|3天|4.11176|**3.29204**|6.51714|\n|nyc|dc|0.1|5天|4.11176|**3.22782**|3.50503|\n|nyc|dc|0.1|7天|4.11176|**3.09117**|3.35844|\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|dc|nyc|0.2|1天|5.35244|**5.15155**|8.01029|\n|dc|nyc|0.2|3天|5.35244|**4.83186**|5.52622|\n|dc|nyc|0.2|5天|5.35244|**4.79484**|5.30417|\n|dc|nyc|0.2|7天|5.35244|**4.83927**|6.07645|\n|dc|nyc|0.2|9天|5.35244|**4.93593**|5.96554|\n|dc|chicago|0.2|1天|**3.65903**|3.67704|46.02469|\n|dc|chicago|0.2|3天|3.65903|**3.38682**|4.22828|\n|dc|chicago|0.2|5天|3.65903|**3.39081**|4.37432|\n|dc|chicago|0.2|7天|3.65903|**3.16186**|3.56052|\n|dc|chicago|0.2|9天|3.65903|**3.12768**|3.39922|\n|nyc|chicago|0.2|1天|5.17356|**4.43069**|11.41116|\n|nyc|chicago|0.2|3天|5.17356|**3.94628**|4.55703|\n|nyc|chicago|0.2|5天|5.17356|**3.93868**|4.31149|\n|nyc|chicago|0.2|7天|5.17356|**3.46738**|3.59811|\n|nyc|chicago|0.2|9天|5.17356|**3.37643**|3.48236|\n|nyc|dc|0.2|1天|4.11176|**3.58924**|5.95973|\n|nyc|dc|0.2|3天|4.11176|**3.29204**|5.09110|\n|nyc|dc|0.2|5天|4.11176|**3.22782**|4.01670|\n|nyc|dc|0.2|7天|4.11176|**3.09117**|3.34005|\n|nyc|dc|0.2|9天|4.11176|**3.02813**|3.31671|\n|chicago|nyc|0.2|1天|7.48254|**6.19588**|9.18276|\n|chicago|nyc|0.2|3天|7.48254|**5.57436**|5.94807|\n|chicago|nyc|0.2|5天|7.48254|**5.54711**|6.02357|\n|chicago|nyc|0.2|7天|7.48254|**5.26407**|6.02906|\n|chicago|nyc|0.2|9天|7.48254|**5.21905**|5.96555|\n|chicago|dc|0.2|1天|4.32390|**3.87629**|5.75511|\n|chicago|dc|0.2|3天|**4.32390**|4.99620|7.56254|\n|chicago|dc|0.2|5天|4.32390|**3.26380**|4.44143|\n|chicago|dc|0.2|7天|4.32390|**3.15168**|3.65643|\n|chicago|dc|0.2|9天|4.32390|**3.13602**|3.25901|\n\n## 分析Transfer效果在城市中的分布\n\n绿色的点表示transfer效果好于finetune，红色代表差于finetune\n\n#### Target City DC\n\n左侧为 Chicago=>DC，Overall result ：Finetune 3.13602，Transfer 3.25901\n\n右侧为 NYC=>DC，Overall result ：Finetune 3.02813，Transfer 3.31671\n\n![1567254312266](..\\src\\image\\transfer_dc.png)\n\n#### Target City NYC\n\n左侧为 DC => NYC，Overall result ：Finetune 4.93593，Transfer 5.96554\n\n右侧为 Chicago =>NYC，Overall result ：Finetune 5.21905，Transfer 5.96555\n\n![1567253682671](..\\src\\image\\transfer_nyc.png)\n\n#### Target City Chicago\n\n左侧为 NYC=>Chicago，Overall result ：Finetune 3.37643，Transfer 3.48236\n\n右侧为 DC=>Chicago，Overall result ：Finetune 3.12768，Transfer 3.39922\n\n![1567255183794](..\\src\\image\\transfer_chicago.png)"
  },
  {
    "path": "docs/sphinx/_build/_sources/md_file/uctb_group.md.txt",
    "content": "## About us (UCTB Group)\n\n### PI\n\n**Leye Wang**  \n\n```From Feb 2019, till now.```\n\nAssistant professor @ Key Lab of High Confidence Software Technologies, Department of Computer Science & Technology, Peking University.\n\nEmail: [leyewang@pku.edu.cn](mailto:leyewang@pku.edu.cn) \n\n[Leye Wang's HomePage](https://cs.pku.edu.cn/info/1174/2334.htm)\n\n______\n\n**Longbiao Chen**  \n\n```From March 2022, till now.```\n\nAssociate professor @ Department of Computer Science, Xiamen University, China\n\nEmail: [longbiaochen@xmu.edu.cn](mailto:longbiaochen@xmu.edu.cn) \n\n[Longbiao Chen's HomePage](https://longbiao.crowdsensing.cn/)\n\n### Key Contributors\n\n**Di Chai** (active)\n\n```From Feb 2019, till now.```\n\nPh.D student in computer science and engineering at Hong Kong University of Science and Technology.\n\nEmail: dchai@cse.ust.hk\n\n______\n\n**Liyue Chen** (active)\n\n```From Nov 2019, till now.```\n\nPh.D student in Peking University.\n\nEmail:  chenliyue2019@gmail.com\n\n------\n\n**Jiangyi Fang** (active)\n\n```From April 2022, till now.```\n\nUndergraduate student majored in Automation in Huazhong University of Science and Technology.\n\nEmail:  fangjiangyi2001@gmail.com\n\n------\n\n**Yayao Hong** (active)\n\n```From Sep 2022, till now.```\n\nMaster student in Fujian Key Laboratory of Sensing and Computing for Smart Cities at Xiamen University.\n\nEmail:  hyymmmint@stu.xmu.edu.cn\n\n------\n\n**Tengfei Liu** (active)\n\n```From March 2023, till now.```\n\nUndergraduate student in computer science and technology at China University of Geosciences.\n\nEmail:  tf66366@cug.edu.cn\n\n------\n**Xiuhuai Xie** (active)\n\n```From July 2023, till now.```\n\nPostgraduate student majored in Computer Technology in Xiamen University.\nEmail: trafalgar2001@163.com\n\n### Past Contributors\n\n**Hang Zhu**\n\n```From March 2022, Jul 2023.```\n\nMaster student in Fujian Key Laboratory of Sensing and Computing for Smart Cities at Xiamen University.\n\nEmail:  zhuhang@stu.xmu.edu.cn\n\n------\n\n**Jin Xu**\n\n```From Jul 2019 to Aug 2019.```\n\nUndergraduate student in Peking University majoring in Data Science and Big Data Technology.\n\nEmail: jinxu@pku.edu.cn\n\n______\n\n**Wenjie Yang**\n\n```From Nov 2019 to Aug 2020.```\n\nMaster student in computer science and engineering at Hong Kong University of Science and Technology.\n\nEmail: wjyccs@gmail.com\n\n______\n\n**Xueqiao Xu**\n\n```From Jan 2020 to Jul 2020.```\n\nHe got his bachelor' degree in Peking University majoring in Data Science and Big Data Technology.\n\nEmail:  snowbridge@foxmail.com\n\n------\n\n**Zhenyu Cui**\n\n```From May 2020 to Nov 2020.```\n\nGraduate student in University of Chinese Academy of Sciences, majoring in Computer Vision and Deep Learning.\n\nEmail:  cuizhenyu18@mails.ucas.ac.cn\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/md_file/urban_dataset.md.txt",
    "content": "# Urban Datasets\n\nUCTB is designed for urban computing in various scenarios. Currently, It releases [a public dataset repository](https://github.com/uctb/Urban-Dataset) including bike sharing, ride sharing, traffic speed, and pedestrian counting applications. **If you are interested in this project, making a contribution to the dataset is strongly welcomed :)**\n\n## Datasets Overview\n\nCurrently, UCTB offers the following datasets in 7 scenarios, with detailed information provided in the table below. We are constantly working to release more datasets in the future.\n\n| **Application**  |        **City**        |     **Time Range**     | **Temporal Granularity** |                                                      **Dataset Link**                                                       |\n|:----------------:|:----------------------:|:----------------------:|:------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|\n|   Bike-sharing   |          NYC           | 2013.07.01-2017.09.30  |        5 minutes         |            [66.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip)             | \n|   Bike-sharing   |        Chicago         | 2013.07.01-2017.09.30  |        5 minutes         |          [30.2M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip)           | \n|   Bike-sharing   |           DC           | 2013.07.01-2017.09.30  |        5 minutes         |             [31.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip)             | \n| Pedestrian Count |       Melbourne        | 2021.01.01-2022.11.01  |        60 minutes        | [1.18M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip) |\n|  Vehicle Speed   |           LA           | 2012.03.01-2012.06.28  |        5 minutes         |            [11.8M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip)             |\n|  Vehicle Speed   |          BAY           | 2017.01.01-2017.07.01  |        5 minutes         |            [27.9M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip)            |\n|   Taxi Demand    |        Chicago         | 2013.01.01-2018.01.01  |        15 minutes        |          [6.1M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|       Bus        |          NYC           | 2022.02.01-2024.01.13  |         60 mins          |             [4.89M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip)             |\n|      Metro       |          NYC           | 2022.02.01-2023.12.21  |         60 mins          |           [11.3M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip)           |\n|   Traffic Flow   |         Luzern         | 2015.01.01-2016.01.01  |          3 mins          |            [21M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Flow/3_minutes/Flow_Luzern.zip)            |\n|   Ride-sharing   |  Chicago (community)   | 2013.01.01-2018.01.01  |         15 mins          |          [6.06](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|   Ride-sharing   | Chicago (census tract) | 2013.01.01-2018.01.01  |         15 mins          |    [10M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip)     |\n|   Ride-sharing   |          NYC           | 2009.01.01-2023.06.01  |          5 mins          |            [36.9M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/5_minutes/Taxi_NYC.zip)             |\n\n## Bike Datasets\nThe bike-sharing datasets are collected from U.S. open data portals including New York City (NYC, https://www.citibikenyc.com/system-data), Chicago (CHI, https://www.divvybikes.com/system-data), and DC (https://www.capitalbikeshare.com/system-data). The dataset time span for all three cities is more than four years. The total number of historical flow records is around 49 million, 13 million, and 14 million in NYC, Chicago, and DC, respectively, and each record contains the start station, start time, stop station, stop time, etc.\n\nThe following shows the map visualization of bike stations in NYC, Chicago, and DC.\n\n<div style=\"display: flex;\">\n  <img src=\"https://camo.githubusercontent.com/eb6a2130ac83330fa6e79276f561c3966c79b7cc90b6cba5b79980127faaa316/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f4e59432e6a7067\" alt=\"图片1\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/9bb00c6ffb052701433ec46dfe52e96365014a2aa3eab825dc4f52e319ff3d1d/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f4368696361676f2e6a7067\" alt=\"图片2\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/a57455f9f9ccba9ed12ec57b3d5d805d75f4577278c824834ea429dc844cf976/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f44432e6a7067\" alt=\"图片3\" style=\"flex: 1; max-width: 300px; height: auto;\">\n</div>\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Bike/\n\n## Bus Datasets\nThe bus datasets are collected from DATA.NY.GOV: MTA Bus Hourly Ridership. This dataset is provided by the Metropolitan Transportation Authority and is available for public download. It offers bus ridership estimates on an hourly basis by bus route. Data collection started from February 2022 and has been regularly updated. The Bus_NYC dataset includes data up to January 13, 2024. The latest version can be accessed on the website mentioned above. The station info data is downloaded from NYU | Faculty Digital Archive: New York City Bus Routes, Dec 2019. It does not encompass all bus routes. So we discarded the traffic data for bus routes where station information was not found, ultimately retaining 226 bus routes.\nFollowing shows the map-visualization of Bus_NYC datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Bus.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Bus\n\n## Speed Datasets\nThe two traffic speed datasets are widely used in STTP research: METR-LA and PEMS-BAY from Los Angeles (LA) County and Bay Area, respectively. In METR-LA, 207 sensors record highway vehicles’ speeds for four months; In PEMS-BAY, there are 325 sensors for six months. Each sensor can be seen as a station.\n\nFollowing shows the map-visualization of METR-LA and PEMS-BAY.\n<div style=\"display: flex;\">\n  <img src=\"https://camo.githubusercontent.com/7beb63775a5bcd043923b5b749896af2d10358bc30e2c974f07a882e5b70b20a/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f4d4554525f4c412e706e67\" alt=\"图片1\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/091bdeb27f8c007a2b19adfe23c48e072d90f157cd033932dbd773cb47c55dad/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f50454d535f4241592e706e67\" alt=\"图片2\" style=\"flex: 1; max-width: 300px; height: auto;\">\n</div>\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Speed/\n\n## Pedestrian Datasets\nThe pedestrian datasets are collected from open data website of Melbourne. The full datasets' timespan is over 10 years and the datasets are still being updated at a fixed frequency (i.e., 60 minutes). Due to the fact that some sites were not set up in the early days and some sites lacked data, we only choose about a year in temporal dimension and 55 stations in spatial dimension. There is also accessible information about sensors on the same website. In the dataset of sensor information, we obtain the name, the sensor's ID, the sensor's status(whether it is active or not), the latitude and longtitude of each sensor.\nFollowing shows the map-visualization of Pedestrian datasets in Melbourne.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Pedestrain_Melbourne.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Pedestrian\n\n## Taxi Datasets\nThe Taxi datasets are collected from the city of Chicago's open data portal and the city of New York's open data portal, where you are able to freely download Chicago city's and NYC's datasets for your own analysis. The datasets record taxi trips from these dimensions listed below: pickup and dropoff time, pickup and dropoff location, fee etc. In our dataset, we only consider the pickup info of each record. You can conduct more comprehensive analysis with the help of our datasets and the website.\n\nTaxi Chicago Dataset\nFacts in dataset description\n\nThere are two candidate spatial discretization information: census tract and community area.\nFor each record, it will aggregate census tract granularity into community area due to privacy preserve.\nWhich granularity to choose\n\nThus, we need to choose a proper granularity. According to the needs of downstream tasks (Spatio-temporal traffic prediction), we summarize two principles of spatial granularity selection:\n\nSpatial granularity as small as possible (especially in high-demand area).\nDemamd aggregated due to privacy as few as possible.\nOn one hand, time distribution of taxi demand in downtown is dense, and the probability of being aggregated is small. on the other hand, the time distribution of taxi demand in the suburbs is sparse, and the probability of being aggregated is high.\n\nFinal datasets we open\n\nWe finally choose to process two datasets: one is Taxi_Chicago, where only spatial granularity community area is used; another is Taxi_fine_grained_Chicago, where community area is used in suburbs while census tract is used in downtown.\n\nWe highly recommend that you conduct more analysis on Taxi_fine_grained_Chicago. By the way, we have adopted a special operation that taxi demand of specific census tract in 15-minute time window equal or less than 2 will be set 2. This operation won't affect much because all of aggregation situation is ultimately caused by insufficient demand.\n\nFollowing shows the map-visualization of Taxi_Chicago datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Chicago_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nFollowing shows the map-visualization of Taxi_fine_grained_Chicago datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Chicago_fine_grained_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nTaxi NYC Datasets\nWe collect Taxi NYC dataset from these two websites: https://opendata.cityofnewyork.us/ and https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page. We also obtain information of taxi zones in New York from this website. As a result of size of dataset, we put it on the link with extraction code gw6p.\n\nFollowing shows the map-visualization of Taxi_NYC datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Taxi\n\n## Metro Datasets\nThe metro datasets are collected from DATA.NY.GOV: MTA Subway Hourly Ridership. The Metro_NYC dataset is provided by the Metropolitan Transportation Authority and is available for public download. It offers estimates of subway ridership on an hourly basis by subway station complex. Data collection started from February 2022 and has been regularly updated. The Metro_NYC dataset includes data up to December 21, 2023. The latest version can be accessed on the website mentioned above.\n\nFollowing shows the map-visualization of station complex in NYC.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Metro.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Metro\n\n## Flow Speed Datasets\nThe traffic flow datasets are collected from UTD19 - Research Collection. UTD19 is a large-scale traffic data set from over 20000 stationary detectors on urban roads in 40 cities worldwide making it the largest multi-city traffic data set publically available. In our dataset, we only consider the data for the city of Luzern. The dataset enriched location information of sensors with further attributes describing the location of the sensor with respect to the road network.\nFollowing shows the map-visualization of station complex in Luzern.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Luzern_Flow.png\" alt=\"Image\" style=\"max-width: 400px; height: auto;\">\n\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Flow\n\n## Load UCTB Dataset\n\n<!-- TODO: 介绍pickle -->\nThe `pickle` module is an external library that comes built-in with Python and provides functionality for converting Python objects into a byte stream (serialization) and restoring them back to their original state (deserialization). We use it to help data format instances to transform between memory and disk.\n\n### Dataset format\n\nWe've collected some public datasets and processing them into UCTB dataset format. UCTB dataset is a python build-in dictionary object that could be loaded by pickle package. Here is the example of UCTB dataset. \n\n```python\n# Let's say ``my_dataset`` is your dataset.\nmy_dataset = {\n    \"TimeRange\": ['YYYY-MM-DD', 'YYYY-MM-DD'],\n    \"TimeFitness\": 60, # Minutes\n    \n    \"Node\": {\n        \"TrafficNode\": np.array, # With shape [time, num-of-node]\n        \"TrafficMonthlyInteraction\": np.array, # With shape [month, num-of-node. num-of-node]\n        \"StationInfo\": list # elements in it should be [id, build-time, lat, lng, name]\n        \"POI\": []\n    },\n\n    \"Grid\": {\n        \"TrafficGrid\": [],\n        \"GridLatLng\": [],\n        \"POI\": []\n    },\n\n    \"ExternalFeature\": {\n         \"Weather\": [time, weather-feature-dim]\n    }\n}\n```\n\n### Use datasets from Urban Datasets\n\nIn this section, we will introduce how to get the dataset from Urban_Dataset and read the dataset using python.\n\nYou are proposed to download the zip file from the [link](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip) and unzip the file. Let's say the following scripts are placed at the same directory with the dataset.\n\n```python\nimport pickle as pkl\nimport numpy as np\ndata_path = 'Pedestrian_Melbourne.pkl'\nwith open(data_path,'rb') as fp:\n    data = pkl.load(fp)\n```\n\nTake a look at the necessary information about the dataset:\n\n```python\n# Traffic data \nprint('Data time range', data['TimeRange'])\nprint('Traffic data shape:', np.shape(data['Node']['TrafficNode']))\n# The first dimension of data['Node']['TrafficNode'] is the length of time-sequence.\n# The second dimension is the number of stations.\nprint('Time fitness:', data['TimeFitness'], 'minutes')\nprint('Time sequence length:', data['Node']['TrafficNode'].shape[0])\nprint('Number of stations:', data['Node']['TrafficNode'].shape[1])\n```\n\n    Data time range ['2021-01-01', '2022-11-01']\n    Traffic data shape: (16056, 55)\n    Time fitness: 60 minutes\n    Time sequence length: 16056\n    Number of stations: 55\n\nVisualize the distribution of the traffic data:\n\n```python\nimport matplotlib.pyplot as plt\nplt.plot(data['Node']['TrafficNode'][:, 0])\nplt.show()\n```\n\n![png](src/image/toturial_p1_dataplot.png)\n\n## How to get the datasets at other granularities?\nWe could merge the fine-grained data to obtain the datasets at other granularities (e.g., by summing the 12 flows from the 5-minutes datasets to obtain 60-minutes datasets). UCTB provides the API to merge data. You could specify MergeIndex and MergeWay in the NodeTrafficLoader and GridTrafficLoader. Here is an example:\n```python\nfrom UCTB.dataset import NodeTrafficLoader\n\n# loading 5-minutes datasets\n\ndata_loader = NodeTrafficLoader(dataset=\"Bike\", city=\"NYC\") \nprint(data_loader.dataset.node_traffic.shape) # with shape (446976, 820)\n\ndata_loader = NodeTrafficLoader(dataset=\"Bike\", city=\"NYC\", MergeIndex=12, MergeWay=\"sum\")\nprint(data_loader.dataset.node_traffic.shape) # with shape (37248, 820)\n```\n## Build your own datasets\n\nIf you want to apply uctb dataloaders to your dataset, make your dataset compatible with the template as section 3.2.1 shown. And then save it with package ``pickle`` to a local path ``pkl_file_name``.\n\n```python\nimport pickle\npkl_file_name = './my_dataset.pkl'  \nwith open(pkl_file_name, 'wb') as handle:\n    pickle.dump(my_dataset, handle, protocol=pickle.HIGHEST_PROTOCOL)\n```\n\nFinally, you can make uses of your dataset by UCTB's loader APIs:\n\n```python\ndata_loader = NodeTrafficLoader(dataset=pkl_file_name)\n```\n\nAlso, we provide interface to help build your own dataset, through which we clarify whether a field is necessary or optional when building a UCTB dataset.\n\nTo build a UCTB dataset, it is necessary to provide variables listed as below.\n\n|Variable_name|Description|\n|:--|:--|\n|time_fitness|The length of the interval between adjacent slots|\n|time_range| The time interval at the beginning and end of the data |\n|traffic_node| The spatio-temporal information |\n|node_satation_info| The basic information of each data collecting node |\n|dataset_name| Name of the dataset |\n|city| A variable used to integrate holiday and weather information to traffic data|\n\nThen, use the specified path to save the dataset, otherwise it will be saved in the current run-time path.\n\nAlthough it's diffcult to form an integrated function to include all situation you may meet during the transforming process, there are some procedures you might obey to simplify the data preprocessing.\n\n- Data preprocessing\n    1. Zero values\n    2. Missing values(NA)\n    3. Unknown values\n    4. Abnormal values\n    5. duplicates\n    6. Statistics(station number and time slots)\n- Dictionary building\n    - Basic information(time range and time fitness)\n    - Traffic node building\n        - Spatio-temporal raster data building\n            1. Initialization\n            2. iterate raw data table and fill the matrix\n        - Station information\n    - Traffic grid building\n    - External feature\n\nNow, we assume that you have already finished variable preparation. UCTB provide API to assist you with dataset building.\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago')\n```\n\nAlso, if you want to check what fields are in your datasets, set the argument ``print_dataset`` to ``True``.\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago', print_dataset=True)\n```\n\nOutput:\n\n    dataset[TimeRange]:<class 'list'>  (len=2)\n    dataset[TimeFitness]:<class 'int'>\n    dataset[Node]:<class 'dict'>{\n        dataset[Node][TrafficNode]:<class 'numpy.ndarray'>  (shape=(37248, 532))\n        dataset[Node][StationInfo]:<class 'list'>  (len=(532, 5))\n        dataset[Node][TrafficMonthlyInteraction]:<class 'NoneType'>\n    }\n    dataset[Grid]:<class 'dict'>{\n        dataset[Grid][TrafficGrid]:<class 'NoneType'>\n        dataset[Grid][GridLatLng]:<class 'NoneType'>\n    }\n    dataset[ExternalFeature]:<class 'dict'>{\n        dataset[ExternalFeature][Weather]:<class 'list'>  (len=0)\n    }\n    dataset[LenTimeSlots]:<class 'int'>\n\nWhat's more, if you want to integrate additional information of the dataset, just specify the optional argument as bellow.\n\n|Variable_name|Description|\n|:--|:--|\n|traffic_monthly_interaction| The interactive information among data collecting nodes. |\n|node_poi| Point of interests conformed with node format|\n|grid_poi| Point of interests conformed with grid format|\n|traffic_grid| The spatio-temporal information in grid format. |\n|gird_lat_lng| The basic information of each data collecting grid.|\n|external_feature_weather| The weather information of each day. |\n\nfor example, specify the argument ``external_feature_weather`` with numpy.array object.\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago', \n                print_dataset=True, external_feature_weather=np.zeros([37248,26]))\n```\n\nThe code above use zero matrix to specify the argument ``external_feature_weather``. While in practical application scenario, you should substitute it with real feather matrix. The first dimension of the matrx is the number of time slots, and the second dimension corresponds to the dimension of weather features."
  },
  {
    "path": "docs/sphinx/_build/_sources/md_file/visualization_tool.md.txt",
    "content": "# Visualization-tool\n\nWe have developed a tool that integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis. Welcome to visit the [website](http://39.107.116.221/) for a trial.\n\n## Quick Start\n\n### Start with predefined dataset\n\nYou can click on the dropdown menu in the `predefined` module of the `Data Loader`, select the dataset you need, and click `confirm` to obtain the required diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_1.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n### Start with prediction and ground truth\n\nYou can upload specifically formatted TSV files for prediction and ground truth in the `upload` module of the Data Loader. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_2.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n### Start with prediction, ground truth and spatial information\n\nYou can upload specifically formatted TSV files for prediction, ground truth, and spatial information in the `upload` module of the `Data Loader`. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_3.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n###  Start with prediction, ground truth and temporal information\n\nYou can upload specifically formatted TSV files for prediction, and ground truth in the `upload` module of the 'Data Loader', along with the corresponding temporal information. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_4.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n### Start with prediction, ground truth as well as spatial and temporal information\n\nYou can upload specifically formatted TSV files for prediction, ground truth, and spatial information in the `upload` module of the `Data Loader`, along with the corresponding temporal information. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_5.png\" alt=\".img\" style=\"zoom: 33%;\" />\n\n## Contribute to our project.\n\nThe visualization-tool offers two usage options, which are accessing through the [website](http://39.107.116.221/), or using the source code(for contribution).\n\n**Step 1: Requirements**\n\n```vue\nnode == 16.14.0\nnpm == 8.3.1\n```\n\n**Step 2: Clone repository and install dependencies**\n\n```Vue\ngit clone https://github.com/uctb/visualization-tool-UCTB.git \ncd visualization-tool-UCTB \nnpm install\n```\n\n**Step 3: Start**\n\n```Vue\nnpm run serve\n```\n\nThen you will see the following prompt on the screen:\n\n```vue\n App running at:\n  - Local:   http://localhost:xxxx/ \n  - Network: http://ip:xxxx/\n```\n\nYou can customize the visualization tool in the source code to achieve visual effects that better fit the objectives. To better assist you in achieving personalization of the visualization tool, we recommend following these steps to implement it.\n\n**Step 1: Create your own component**\n\n```vue\n<template>\n<div>Your own HTML</div>\n</template>\n\n<script>\nexport default {\n\tname: 'your own component name',\n    data(){}\n}\n</script>\n\n<style scoped>\n /*Your own CSS*/\n</style>\n```\n\n**Step 2: Importing component in App.vue**\n\n```vue\n<script>\nimport YourOwnComponent from \"./components/YourOwnComponent.vue\"\nexport default {\n\tname: 'App',\n    components: {\n     YourOwnComponent\n    }\n}\n</script>\n```\n\nMore instructions on the usage of Vue can be referred to on the [website](https://v2.vuejs.org/). **If you have any interesting or novel ideas, we highly welcome your pull request:)**"
  },
  {
    "path": "docs/sphinx/_build/_sources/modules.rst.txt",
    "content": "UCTB\n====\n\n.. toctree::\n   :maxdepth: 4\n\n   UCTB\n"
  },
  {
    "path": "docs/sphinx/_build/_sources/update_guide.txt",
    "content": "The first thing is to install the UCTB library, in fact, if you want to update successfully, you must first install the UCTB library successfully。\n\nThe second thing to do is to install the Sphinx-related library functions locally. Here are some of the related versions。\npip install Sphinx==5.1.1\npip install sphinx-markdown-tables==0.0.17\npip install sphinx-rtd-theme==1.2.1\npip install sphinxcontrib-applehelp==1.0.2\npip install sphinxcontrib-devhelp==1.0.2\npip install sphinxcontrib-htmlhelp==2.0.0\npip install sphinxcontrib-jsmath==1.0.1\npip install sphinxcontrib-qthelp==1.0.3\npip install sphinxcontrib-serializinghtml==1.1.5\npip install rtcat-sphinx-theme==0.1.1\npip install recommonmark==0.7.1\npip install commonmark==0.9.1\npip install sphinx-markdown-tables==0.0.17\n\nNext, locate the.md file that corresponds to the section you want to update,\nIf you want to add text, just copy and paste it, if you want to add a big title, you can use the form of a # title, if you want to add a secondary title, you can use the form of a ## title, and so on.\n\nWhen update docstrings, run this code in cmd:\nsphinx-apidoc -o . ../../UCTB\nsphinx-build -b html . ..\nsphinx-build -b html . _build\nThen you can get the html file generated after the update.\n"
  },
  {
    "path": "docs/sphinx/_build/_static/_sphinx_javascript_frameworks_compat.js",
    "content": "/*\n * _sphinx_javascript_frameworks_compat.js\n * ~~~~~~~~~~\n *\n * Compatability shim for jQuery and underscores.js.\n *\n * WILL BE REMOVED IN Sphinx 6.0\n * xref RemovedInSphinx60Warning\n *\n */\n\n/**\n * select a different prefix for underscore\n */\n$u = _.noConflict();\n\n\n/**\n * small helper function to urldecode strings\n *\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL\n */\njQuery.urldecode = function(x) {\n    if (!x) {\n        return x\n    }\n    return decodeURIComponent(x.replace(/\\+/g, ' '));\n};\n\n/**\n * small helper function to urlencode strings\n */\njQuery.urlencode = encodeURIComponent;\n\n/**\n * This function returns the parsed url parameters of the\n * current request. Multiple values per key are supported,\n * it will always return arrays of strings for the value parts.\n */\njQuery.getQueryParameters = function(s) {\n    if (typeof s === 'undefined')\n        s = document.location.search;\n    var parts = s.substr(s.indexOf('?') + 1).split('&');\n    var result = {};\n    for (var i = 0; i < parts.length; i++) {\n        var tmp = parts[i].split('=', 2);\n        var key = jQuery.urldecode(tmp[0]);\n        var value = jQuery.urldecode(tmp[1]);\n        if (key in result)\n            result[key].push(value);\n        else\n            result[key] = [value];\n    }\n    return result;\n};\n\n/**\n * highlight a given string on a jquery object by wrapping it in\n * span elements with the given class name.\n */\njQuery.fn.highlightText = function(text, className) {\n    function highlight(node, addItems) {\n        if (node.nodeType === 3) {\n            var val = node.nodeValue;\n            var pos = val.toLowerCase().indexOf(text);\n            if (pos >= 0 &&\n                !jQuery(node.parentNode).hasClass(className) &&\n                !jQuery(node.parentNode).hasClass(\"nohighlight\")) {\n                var span;\n                var isInSVG = jQuery(node).closest(\"body, svg, foreignObject\").is(\"svg\");\n                if (isInSVG) {\n                    span = document.createElementNS(\"http://www.w3.org/2000/svg\", \"tspan\");\n                } else {\n                    span = document.createElement(\"span\");\n                    span.className = className;\n                }\n                span.appendChild(document.createTextNode(val.substr(pos, text.length)));\n                node.parentNode.insertBefore(span, node.parentNode.insertBefore(\n                    document.createTextNode(val.substr(pos + text.length)),\n                    node.nextSibling));\n                node.nodeValue = val.substr(0, pos);\n                if (isInSVG) {\n                    var rect = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n                    var bbox = node.parentElement.getBBox();\n                    rect.x.baseVal.value = bbox.x;\n                    rect.y.baseVal.value = bbox.y;\n                    rect.width.baseVal.value = bbox.width;\n                    rect.height.baseVal.value = bbox.height;\n                    rect.setAttribute('class', className);\n                    addItems.push({\n                        \"parent\": node.parentNode,\n                        \"target\": rect});\n                }\n            }\n        }\n        else if (!jQuery(node).is(\"button, select, textarea\")) {\n            jQuery.each(node.childNodes, function() {\n                highlight(this, addItems);\n            });\n        }\n    }\n    var addItems = [];\n    var result = this.each(function() {\n        highlight(this, addItems);\n    });\n    for (var i = 0; i < addItems.length; ++i) {\n        jQuery(addItems[i].parent).before(addItems[i].target);\n    }\n    return result;\n};\n\n/*\n * backward compatibility for jQuery.browser\n * This will be supported until firefox bug is fixed.\n */\nif (!jQuery.browser) {\n    jQuery.uaMatch = function(ua) {\n        ua = ua.toLowerCase();\n\n        var match = /(chrome)[ \\/]([\\w.]+)/.exec(ua) ||\n            /(webkit)[ \\/]([\\w.]+)/.exec(ua) ||\n            /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec(ua) ||\n            /(msie) ([\\w.]+)/.exec(ua) ||\n            ua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec(ua) ||\n            [];\n\n        return {\n            browser: match[ 1 ] || \"\",\n            version: match[ 2 ] || \"0\"\n        };\n    };\n    jQuery.browser = {};\n    jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;\n}\n"
  },
  {
    "path": "docs/sphinx/_build/_static/basic.css",
    "content": "/*\n * basic.css\n * ~~~~~~~~~\n *\n * Sphinx stylesheet -- basic theme.\n *\n * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n/* -- main layout ----------------------------------------------------------- */\n\ndiv.clearer {\n    clear: both;\n}\n\n/* -- relbar ---------------------------------------------------------------- */\n\ndiv.related {\n    width: 100%;\n    font-size: 90%;\n}\n\ndiv.related h3 {\n    display: none;\n}\n\ndiv.related ul {\n    margin: 0;\n    padding: 0 0 0 10px;\n    list-style: none;\n}\n\ndiv.related li {\n    display: inline;\n}\n\ndiv.related li.right {\n    float: right;\n    margin-right: 5px;\n}\n\n/* -- sidebar --------------------------------------------------------------- */\n\ndiv.sphinxsidebarwrapper {\n    padding: 10px 5px 0 10px;\n}\n\ndiv.sphinxsidebar {\n    float: left;\n    width: 230px;\n    margin-left: -100%;\n    font-size: 90%;\n    word-wrap: break-word;\n    overflow-wrap : break-word;\n}\n\ndiv.sphinxsidebar ul {\n    list-style: none;\n}\n\ndiv.sphinxsidebar ul ul,\ndiv.sphinxsidebar ul.want-points {\n    margin-left: 20px;\n    list-style: square;\n}\n\ndiv.sphinxsidebar ul ul {\n    margin-top: 0;\n    margin-bottom: 0;\n}\n\ndiv.sphinxsidebar form {\n    margin-top: 10px;\n}\n\ndiv.sphinxsidebar input {\n    border: 1px solid #98dbcc;\n    font-family: sans-serif;\n    font-size: 1em;\n}\n\ndiv.sphinxsidebar #searchbox input[type=\"text\"] {\n    width: 170px;\n}\n\nimg {\n    border: 0;\n    max-width: 100%;\n}\n\n/* -- search page ----------------------------------------------------------- */\n\nul.search {\n    margin: 10px 0 0 20px;\n    padding: 0;\n}\n\nul.search li {\n    padding: 5px 0 5px 20px;\n    background-image: url(file.png);\n    background-repeat: no-repeat;\n    background-position: 0 7px;\n}\n\nul.search li a {\n    font-weight: bold;\n}\n\nul.search li div.context {\n    color: #888;\n    margin: 2px 0 0 30px;\n    text-align: left;\n}\n\nul.keywordmatches li.goodmatch a {\n    font-weight: bold;\n}\n\n/* -- index page ------------------------------------------------------------ */\n\ntable.contentstable {\n    width: 90%;\n    margin-left: auto;\n    margin-right: auto;\n}\n\ntable.contentstable p.biglink {\n    line-height: 150%;\n}\n\na.biglink {\n    font-size: 1.3em;\n}\n\nspan.linkdescr {\n    font-style: italic;\n    padding-top: 5px;\n    font-size: 90%;\n}\n\n/* -- general index --------------------------------------------------------- */\n\ntable.indextable {\n    width: 100%;\n}\n\ntable.indextable td {\n    text-align: left;\n    vertical-align: top;\n}\n\ntable.indextable ul {\n    margin-top: 0;\n    margin-bottom: 0;\n    list-style-type: none;\n}\n\ntable.indextable > tbody > tr > td > ul {\n    padding-left: 0em;\n}\n\ntable.indextable tr.pcap {\n    height: 10px;\n}\n\ntable.indextable tr.cap {\n    margin-top: 10px;\n    background-color: #f2f2f2;\n}\n\nimg.toggler {\n    margin-right: 3px;\n    margin-top: 3px;\n    cursor: pointer;\n}\n\ndiv.modindex-jumpbox {\n    border-top: 1px solid #ddd;\n    border-bottom: 1px solid #ddd;\n    margin: 1em 0 1em 0;\n    padding: 0.4em;\n}\n\ndiv.genindex-jumpbox {\n    border-top: 1px solid #ddd;\n    border-bottom: 1px solid #ddd;\n    margin: 1em 0 1em 0;\n    padding: 0.4em;\n}\n\n/* -- domain module index --------------------------------------------------- */\n\ntable.modindextable td {\n    padding: 2px;\n    border-collapse: collapse;\n}\n\n/* -- general body styles --------------------------------------------------- */\n\ndiv.body p, div.body dd, div.body li, div.body blockquote {\n    -moz-hyphens: auto;\n    -ms-hyphens: auto;\n    -webkit-hyphens: auto;\n    hyphens: auto;\n}\n\na.headerlink {\n    visibility: hidden;\n}\n\nh1:hover > a.headerlink,\nh2:hover > a.headerlink,\nh3:hover > a.headerlink,\nh4:hover > a.headerlink,\nh5:hover > a.headerlink,\nh6:hover > a.headerlink,\ndt:hover > a.headerlink,\ncaption:hover > a.headerlink,\np.caption:hover > a.headerlink,\ndiv.code-block-caption:hover > a.headerlink {\n    visibility: visible;\n}\n\ndiv.body p.caption {\n    text-align: inherit;\n}\n\ndiv.body td {\n    text-align: left;\n}\n\n.first {\n    margin-top: 0 !important;\n}\n\np.rubric {\n    margin-top: 30px;\n    font-weight: bold;\n}\n\nimg.align-left, .figure.align-left, object.align-left {\n    clear: left;\n    float: left;\n    margin-right: 1em;\n}\n\nimg.align-right, .figure.align-right, object.align-right {\n    clear: right;\n    float: right;\n    margin-left: 1em;\n}\n\nimg.align-center, .figure.align-center, object.align-center {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n\n.align-left {\n    text-align: left;\n}\n\n.align-center {\n    text-align: center;\n}\n\n.align-right {\n    text-align: right;\n}\n\n/* -- sidebars -------------------------------------------------------------- */\n\ndiv.sidebar {\n    margin: 0 0 0.5em 1em;\n    border: 1px solid #ddb;\n    padding: 7px 7px 0 7px;\n    background-color: #ffe;\n    width: 40%;\n    float: right;\n}\n\np.sidebar-title {\n    font-weight: bold;\n}\n\n/* -- topics ---------------------------------------------------------------- */\n\ndiv.topic {\n    border: 1px solid #ccc;\n    padding: 7px 7px 0 7px;\n    margin: 10px 0 10px 0;\n}\n\np.topic-title {\n    font-size: 1.1em;\n    font-weight: bold;\n    margin-top: 10px;\n}\n\n/* -- admonitions ----------------------------------------------------------- */\n\ndiv.admonition {\n    margin-top: 10px;\n    margin-bottom: 10px;\n    padding: 7px;\n}\n\ndiv.admonition dt {\n    font-weight: bold;\n}\n\ndiv.admonition dl {\n    margin-bottom: 0;\n}\n\np.admonition-title {\n    margin: 0px 10px 5px 0px;\n    font-weight: bold;\n}\n\ndiv.body p.centered {\n    text-align: center;\n    margin-top: 25px;\n}\n\n/* -- tables ---------------------------------------------------------------- */\n\ntable.docutils {\n    border: 0;\n    border-collapse: collapse;\n}\n\ntable caption span.caption-number {\n    font-style: italic;\n}\n\ntable caption span.caption-text {\n}\n\ntable.docutils td, table.docutils th {\n    padding: 1px 8px 1px 5px;\n    border-top: 0;\n    border-left: 0;\n    border-right: 0;\n    border-bottom: 1px solid #aaa;\n}\n\ntable.footnote td, table.footnote th {\n    border: 0 !important;\n}\n\nth {\n    text-align: left;\n    padding-right: 5px;\n}\n\ntable.citation {\n    border-left: solid 1px gray;\n    margin-left: 1px;\n}\n\ntable.citation td {\n    border-bottom: none;\n}\n\n/* -- figures --------------------------------------------------------------- */\n\ndiv.figure {\n    margin: 0.5em;\n    padding: 0.5em;\n}\n\ndiv.figure p.caption {\n    padding: 0.3em;\n}\n\ndiv.figure p.caption span.caption-number {\n    font-style: italic;\n}\n\ndiv.figure p.caption span.caption-text {\n}\n\n/* -- field list styles ----------------------------------------------------- */\n\ntable.field-list td, table.field-list th {\n    border: 0 !important;\n}\n\n.field-list ul {\n    margin: 0;\n    padding-left: 1em;\n}\n\n.field-list p {\n    margin: 0;\n}\n\n.field-name {\n    -moz-hyphens: manual;\n    -ms-hyphens: manual;\n    -webkit-hyphens: manual;\n    hyphens: manual;\n}\n\n/* -- other body styles ----------------------------------------------------- */\n\nol.arabic {\n    list-style: decimal;\n}\n\nol.loweralpha {\n    list-style: lower-alpha;\n}\n\nol.upperalpha {\n    list-style: upper-alpha;\n}\n\nol.lowerroman {\n    list-style: lower-roman;\n}\n\nol.upperroman {\n    list-style: upper-roman;\n}\n\ndl {\n    margin-bottom: 15px;\n}\n\ndd p {\n    margin-top: 0px;\n}\n\ndd ul, dd table {\n    margin-bottom: 10px;\n}\n\ndd {\n    margin-top: 3px;\n    margin-bottom: 10px;\n    margin-left: 30px;\n}\n\ndt:target, .highlighted {\n    background-color: #fbe54e;\n}\n\ndl.glossary dt {\n    font-weight: bold;\n    font-size: 1.1em;\n}\n\n.optional {\n    font-size: 1.3em;\n}\n\n.sig-paren {\n    font-size: larger;\n}\n\n.versionmodified {\n    font-style: italic;\n}\n\n.system-message {\n    background-color: #fda;\n    padding: 5px;\n    border: 3px solid red;\n}\n\n.footnote:target  {\n    background-color: #ffa;\n}\n\n.line-block {\n    display: block;\n    margin-top: 1em;\n    margin-bottom: 1em;\n}\n\n.line-block .line-block {\n    margin-top: 0;\n    margin-bottom: 0;\n    margin-left: 1.5em;\n}\n\n.guilabel, .menuselection {\n    font-family: sans-serif;\n}\n\n.accelerator {\n    text-decoration: underline;\n}\n\n.classifier {\n    font-style: oblique;\n}\n\nabbr, acronym {\n    border-bottom: dotted 1px;\n    cursor: help;\n}\n\n/* -- code displays --------------------------------------------------------- */\n\npre {\n    overflow: auto;\n    overflow-y: hidden;  /* fixes display issues on Chrome browsers */\n}\n\nspan.pre {\n    -moz-hyphens: none;\n    -ms-hyphens: none;\n    -webkit-hyphens: none;\n    hyphens: none;\n}\n\ntd.linenos pre {\n    padding: 5px 0px;\n    border: 0;\n    background-color: transparent;\n    color: #aaa;\n}\n\ntable.highlighttable {\n    margin-left: 0.5em;\n}\n\ntable.highlighttable td {\n    padding: 0 0.5em 0 0.5em;\n}\n\ndiv.code-block-caption {\n    padding: 2px 5px;\n    font-size: small;\n}\n\ndiv.code-block-caption code {\n    background-color: transparent;\n}\n\ndiv.code-block-caption + div > div.highlight > pre {\n    margin-top: 0;\n}\n\ndiv.code-block-caption span.caption-number {\n    padding: 0.1em 0.3em;\n    font-style: italic;\n}\n\ndiv.code-block-caption span.caption-text {\n}\n\ndiv.literal-block-wrapper {\n    padding: 1em 1em 0;\n}\n\ndiv.literal-block-wrapper div.highlight {\n    margin: 0;\n}\n\ncode.descname {\n    background-color: transparent;\n    font-weight: bold;\n    font-size: 1.2em;\n}\n\ncode.descclassname {\n    background-color: transparent;\n}\n\ncode.xref, a code {\n    background-color: transparent;\n    font-weight: bold;\n}\n\nh1 code, h2 code, h3 code, h4 code, h5 code, h6 code {\n    background-color: transparent;\n}\n\n.viewcode-link {\n    float: right;\n}\n\n.viewcode-back {\n    float: right;\n    font-family: sans-serif;\n}\n\ndiv.viewcode-block:target {\n    margin: -1px -10px;\n    padding: 0 10px;\n}\n\n/* -- math display ---------------------------------------------------------- */\n\nimg.math {\n    vertical-align: middle;\n}\n\ndiv.body div.math p {\n    text-align: center;\n}\n\nspan.eqno {\n    float: right;\n}\n\nspan.eqno a.headerlink {\n    position: relative;\n    left: 0px;\n    z-index: 1;\n}\n\ndiv.math:hover a.headerlink {\n    visibility: visible;\n}\n\n/* -- printout stylesheet --------------------------------------------------- */\n\n@media print {\n    div.document,\n    div.documentwrapper,\n    div.bodywrapper {\n        margin: 0 !important;\n        width: 100%;\n    }\n\n    div.sphinxsidebar,\n    div.related,\n    div.footer,\n    #top-link {\n        display: none;\n    }\n}"
  },
  {
    "path": "docs/sphinx/_build/_static/css/badge_only.css",
    "content": "@charset \"UTF-8\";\n.fa:before {\n  -webkit-font-smoothing: antialiased;\n}\n\n.clearfix {\n  *zoom: 1;\n}\n.clearfix:before, .clearfix:after {\n  display: table;\n  content: \"\";\n}\n.clearfix:after {\n  clear: both;\n}\n\n@font-face {\n  font-family: FontAwesome;\n  font-weight: normal;\n  font-style: normal;\n  src: url(\"../font/fontawesome_webfont.eot\");\n  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\");\n}\n.fa:before {\n  display: inline-block;\n  font-family: FontAwesome;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  text-decoration: inherit;\n}\n\na .fa {\n  display: inline-block;\n  text-decoration: inherit;\n}\n\nli .fa {\n  display: inline-block;\n}\nli .fa-large:before,\nli .fa-large:before {\n  /* 1.5 increased font size for fa-large * 1.25 width */\n  width: 1.875em;\n}\n\nul.fas {\n  list-style-type: none;\n  margin-left: 2em;\n  text-indent: -0.8em;\n}\nul.fas li .fa {\n  width: 0.8em;\n}\nul.fas li .fa-large:before,\nul.fas li .fa-large:before {\n  /* 1.5 increased font size for fa-large * 1.25 width */\n  vertical-align: baseline;\n}\n\n.fa-book:before {\n  content: \"\";\n}\n\n.icon-book:before {\n  content: \"\";\n}\n\n.fa-caret-down:before {\n  content: \"\";\n}\n\n.icon-caret-down:before {\n  content: \"\";\n}\n\n.fa-caret-up:before {\n  content: \"\";\n}\n\n.icon-caret-up:before {\n  content: \"\";\n}\n\n.fa-caret-left:before {\n  content: \"\";\n}\n\n.icon-caret-left:before {\n  content: \"\";\n}\n\n.fa-caret-right:before {\n  content: \"\";\n}\n\n.icon-caret-right:before {\n  content: \"\";\n}\n\n.rst-versions {\n  position: fixed;\n  bottom: 0;\n  left: 0;\n  width: 300px;\n  color: #fcfcfc;\n  background: #1f1d1d;\n  border-top: solid 10px #343131;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  z-index: 400;\n}\n.rst-versions a {\n  color: #0E6FD2;\n  text-decoration: none;\n}\n.rst-versions .rst-badge-small {\n  display: none;\n}\n.rst-versions .rst-current-version {\n  padding: 12px;\n  background-color: #272525;\n  display: block;\n  text-align: right;\n  font-size: 90%;\n  cursor: pointer;\n  color: #27AE60;\n  *zoom: 1;\n}\n.rst-versions .rst-current-version:before, .rst-versions .rst-current-version:after {\n  display: table;\n  content: \"\";\n}\n.rst-versions .rst-current-version:after {\n  clear: both;\n}\n.rst-versions .rst-current-version .fa {\n  color: #fcfcfc;\n}\n.rst-versions .rst-current-version .fa-book {\n  float: left;\n}\n.rst-versions .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions .rst-current-version.rst-out-of-date {\n  background-color: #E74C3C;\n  color: #fff;\n}\n.rst-versions .rst-current-version.rst-active-old-version {\n  background-color: #F1C40F;\n  color: #000;\n}\n.rst-versions.shift-up .rst-other-versions {\n  display: block;\n}\n.rst-versions .rst-other-versions {\n  font-size: 90%;\n  padding: 12px;\n  color: gray;\n  display: none;\n}\n.rst-versions .rst-other-versions hr {\n  display: block;\n  height: 1px;\n  border: 0;\n  margin: 20px 0;\n  padding: 0;\n  border-top: solid 1px #413d3d;\n}\n.rst-versions .rst-other-versions dd {\n  display: inline-block;\n  margin: 0;\n}\n.rst-versions .rst-other-versions dd a {\n  display: inline-block;\n  padding: 6px;\n  color: #fcfcfc;\n}\n.rst-versions.rst-badge {\n  width: auto;\n  bottom: 20px;\n  right: 20px;\n  left: auto;\n  border: none;\n  max-width: 300px;\n}\n.rst-versions.rst-badge .icon-book {\n  float: none;\n}\n.rst-versions.rst-badge .fa-book {\n  float: none;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version {\n  text-align: right;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version .fa-book {\n  float: left;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions.rst-badge .rst-current-version {\n  width: auto;\n  height: 30px;\n  line-height: 30px;\n  padding: 0 6px;\n  display: block;\n  text-align: center;\n}\n\n@media screen and (max-width: 768px) {\n  .rst-versions {\n    width: 85%;\n    display: none;\n  }\n  .rst-versions.shift {\n    display: block;\n  }\n\n  img {\n    width: 100%;\n    height: auto;\n  }\n}\n\n/*# sourceMappingURL=badge_only.css.map */\n"
  },
  {
    "path": "docs/sphinx/_build/_static/css/theme.css",
    "content": "@charset \"UTF-8\";\n* {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n\narticle, aside, details, figcaption, figure, footer, header, hgroup, nav, section {\n  display: block;\n}\n\naudio, canvas, video {\n  display: inline-block;\n  *display: inline;\n  *zoom: 1;\n}\n\naudio:not([controls]) {\n  display: none;\n}\n\n[hidden] {\n  display: none;\n}\n\n* {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n\nhtml {\n  font-size: 100%;\n  -webkit-text-size-adjust: 100%;\n  -ms-text-size-adjust: 100%;\n}\n\nbody {\n  margin: 0;\n}\n\na:hover, a:active {\n  outline: 0;\n}\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\nb, strong {\n  font-weight: bold;\n}\n\nblockquote {\n  margin: 0;\n}\n\ndfn {\n  font-style: italic;\n}\n\nins {\n  background: #ff9;\n  color: #000;\n  text-decoration: none;\n}\n\nmark {\n  background: #ff0;\n  color: #000;\n  font-style: italic;\n  font-weight: bold;\n}\n\npre, code, .rst-content tt, .rst-content code, kbd, samp {\n  font-family: monospace, serif;\n  _font-family: \"courier new\", monospace;\n  font-size: 1em;\n}\n\npre {\n  white-space: pre;\n}\n\nq {\n  quotes: none;\n}\n\nq:before, q:after {\n  content: \"\";\n  content: none;\n}\n\nsmall {\n  font-size: 85%;\n}\n\nsub, sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nul, ol, dl {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n  list-style-image: none;\n}\n\nli {\n  list-style: none;\n}\n\ndd {\n  margin: 0;\n}\n\nimg {\n  border: 0;\n  -ms-interpolation-mode: bicubic;\n  vertical-align: middle;\n  max-width: 100%;\n}\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\nfigure {\n  margin: 0;\n}\n\nform {\n  margin: 0;\n}\n\nfieldset {\n  border: 0;\n  margin: 0;\n  padding: 0;\n}\n\nlabel {\n  cursor: pointer;\n}\n\nlegend {\n  border: 0;\n  *margin-left: -7px;\n  padding: 0;\n  white-space: normal;\n}\n\nbutton, input, select, textarea {\n  font-size: 100%;\n  margin: 0;\n  vertical-align: baseline;\n  *vertical-align: middle;\n}\n\nbutton, input {\n  line-height: normal;\n}\n\nbutton, input[type=\"button\"], input[type=\"reset\"], input[type=\"submit\"] {\n  cursor: pointer;\n  -webkit-appearance: button;\n  *overflow: visible;\n}\n\nbutton[disabled], input[disabled] {\n  cursor: default;\n}\n\ninput[type=\"checkbox\"], input[type=\"radio\"] {\n  box-sizing: border-box;\n  padding: 0;\n  *width: 13px;\n  *height: 13px;\n}\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield;\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\ninput[type=\"search\"]::-webkit-search-decoration, input[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\nbutton::-moz-focus-inner, input::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\ntextarea {\n  overflow: auto;\n  vertical-align: top;\n  resize: vertical;\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd {\n  vertical-align: top;\n}\n\n.chromeframe {\n  margin: 0.2em 0;\n  background: #ccc;\n  color: black;\n  padding: 0.2em 0;\n}\n\n.ir {\n  display: block;\n  border: 0;\n  text-indent: -999em;\n  overflow: hidden;\n  background-color: transparent;\n  background-repeat: no-repeat;\n  text-align: left;\n  direction: ltr;\n  *line-height: 0;\n}\n\n.ir br {\n  display: none;\n}\n\n.hidden {\n  display: none !important;\n  visibility: hidden;\n}\n\n.visuallyhidden {\n  border: 0;\n  clip: rect(0 0 0 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px;\n}\n\n.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus {\n  clip: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  position: static;\n  width: auto;\n}\n\n.invisible {\n  visibility: hidden;\n}\n\n.relative {\n  position: relative;\n}\n\nbig, small {\n  font-size: 100%;\n}\n\n@media print {\n  html, body, section {\n    background: none !important;\n  }\n\n  * {\n    box-shadow: none !important;\n    text-shadow: none !important;\n    filter: none !important;\n    -ms-filter: none !important;\n  }\n\n  a, a:visited {\n    text-decoration: underline;\n  }\n\n  .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  pre, blockquote {\n    page-break-inside: avoid;\n  }\n\n  thead {\n    display: table-header-group;\n  }\n\n  tr, img {\n    page-break-inside: avoid;\n  }\n\n  img {\n    max-width: 100% !important;\n  }\n\n  @page {\n    margin: 0.5cm;\n  }\n  p, h2, .rst-content .toctree-wrapper p.caption, h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  h2, .rst-content .toctree-wrapper p.caption, h3 {\n    page-break-after: avoid;\n  }\n}\n.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 {\n  -webkit-font-smoothing: antialiased;\n}\n\n.clearfix {\n  *zoom: 1;\n}\n.clearfix:before, .clearfix:after {\n  display: table;\n  content: \"\";\n}\n.clearfix:after {\n  clear: both;\n}\n\n/*!\n *  Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n/* FONT PATH\n * -------------------------- */\n@font-face {\n  font-family: 'FontAwesome';\n  src: url(\"../fonts/fontawesome-webfont.eot?v=4.2.0\");\n  src: url(\"../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0\") format(\"embedded-opentype\"), url(\"../fonts/fontawesome-webfont.woff?v=4.2.0\") format(\"woff\"), url(\"../fonts/fontawesome-webfont.ttf?v=4.2.0\") format(\"truetype\"), url(\"../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular\") format(\"svg\");\n  font-weight: normal;\n  font-style: normal;\n}\n.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 {\n  display: inline-block;\n  font: normal normal normal 14px/1 FontAwesome;\n  font-size: inherit;\n  text-rendering: auto;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n/* makes the font 33% larger relative to the icon container */\n.fa-lg {\n  font-size: 1.33333em;\n  line-height: 0.75em;\n  vertical-align: -15%;\n}\n\n.fa-2x {\n  font-size: 2em;\n}\n\n.fa-3x {\n  font-size: 3em;\n}\n\n.fa-4x {\n  font-size: 4em;\n}\n\n.fa-5x {\n  font-size: 5em;\n}\n\n.fa-fw {\n  width: 1.28571em;\n  text-align: center;\n}\n\n.fa-ul {\n  padding-left: 0;\n  margin-left: 2.14286em;\n  list-style-type: none;\n}\n.fa-ul > li {\n  position: relative;\n}\n\n.fa-li {\n  position: absolute;\n  left: -2.14286em;\n  width: 2.14286em;\n  top: 0.14286em;\n  text-align: center;\n}\n.fa-li.fa-lg {\n  left: -1.85714em;\n}\n\n.fa-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em #eee;\n  border-radius: .1em;\n}\n\n.pull-right {\n  float: right;\n}\n\n.pull-left {\n  float: left;\n}\n\n.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 {\n  margin-right: .3em;\n}\n.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 {\n  margin-left: .3em;\n}\n\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n  animation: fa-spin 2s infinite linear;\n}\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n.fa-rotate-90 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n  -webkit-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n\n.fa-rotate-180 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n\n.fa-rotate-270 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n  -webkit-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n\n.fa-flip-horizontal {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0);\n  -webkit-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n\n.fa-flip-vertical {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical {\n  filter: none;\n}\n\n.fa-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n\n.fa-stack-1x, .fa-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n\n.fa-stack-1x {\n  line-height: inherit;\n}\n\n.fa-stack-2x {\n  font-size: 2em;\n}\n\n.fa-inverse {\n  color: #fff;\n}\n\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.fa-glass:before {\n  content: \"\";\n}\n\n.fa-music:before {\n  content: \"\";\n}\n\n.fa-search:before, .icon-search:before {\n  content: \"\";\n}\n\n.fa-envelope-o:before {\n  content: \"\";\n}\n\n.fa-heart:before {\n  content: \"\";\n}\n\n.fa-star:before {\n  content: \"\";\n}\n\n.fa-star-o:before {\n  content: \"\";\n}\n\n.fa-user:before {\n  content: \"\";\n}\n\n.fa-film:before {\n  content: \"\";\n}\n\n.fa-th-large:before {\n  content: \"\";\n}\n\n.fa-th:before {\n  content: \"\";\n}\n\n.fa-th-list:before {\n  content: \"\";\n}\n\n.fa-check:before {\n  content: \"\";\n}\n\n.fa-remove:before,\n.fa-close:before,\n.fa-times:before {\n  content: \"\";\n}\n\n.fa-search-plus:before {\n  content: \"\";\n}\n\n.fa-search-minus:before {\n  content: \"\";\n}\n\n.fa-power-off:before {\n  content: \"\";\n}\n\n.fa-signal:before {\n  content: \"\";\n}\n\n.fa-gear:before,\n.fa-cog:before {\n  content: \"\";\n}\n\n.fa-trash-o:before {\n  content: \"\";\n}\n\n.fa-home:before, .icon-home:before {\n  content: \"\";\n}\n\n.fa-file-o:before {\n  content: \"\";\n}\n\n.fa-clock-o:before {\n  content: \"\";\n}\n\n.fa-road:before {\n  content: \"\";\n}\n\n.fa-download:before, .rst-content tt.download span:first-child:before, .rst-content code.download span:first-child:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-o-down:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-o-up:before {\n  content: \"\";\n}\n\n.fa-inbox:before {\n  content: \"\";\n}\n\n.fa-play-circle-o:before {\n  content: \"\";\n}\n\n.fa-rotate-right:before,\n.fa-repeat:before {\n  content: \"\";\n}\n\n.fa-refresh:before {\n  content: \"\";\n}\n\n.fa-list-alt:before {\n  content: \"\";\n}\n\n.fa-lock:before {\n  content: \"\";\n}\n\n.fa-flag:before {\n  content: \"\";\n}\n\n.fa-headphones:before {\n  content: \"\";\n}\n\n.fa-volume-off:before {\n  content: \"\";\n}\n\n.fa-volume-down:before {\n  content: \"\";\n}\n\n.fa-volume-up:before {\n  content: \"\";\n}\n\n.fa-qrcode:before {\n  content: \"\";\n}\n\n.fa-barcode:before {\n  content: \"\";\n}\n\n.fa-tag:before {\n  content: \"\";\n}\n\n.fa-tags:before {\n  content: \"\";\n}\n\n.fa-book:before, .icon-book:before {\n  content: \"\";\n}\n\n.fa-bookmark:before {\n  content: \"\";\n}\n\n.fa-print:before {\n  content: \"\";\n}\n\n.fa-camera:before {\n  content: \"\";\n}\n\n.fa-font:before {\n  content: \"\";\n}\n\n.fa-bold:before {\n  content: \"\";\n}\n\n.fa-italic:before {\n  content: \"\";\n}\n\n.fa-text-height:before {\n  content: \"\";\n}\n\n.fa-text-width:before {\n  content: \"\";\n}\n\n.fa-align-left:before {\n  content: \"\";\n}\n\n.fa-align-center:before {\n  content: \"\";\n}\n\n.fa-align-right:before {\n  content: \"\";\n}\n\n.fa-align-justify:before {\n  content: \"\";\n}\n\n.fa-list:before {\n  content: \"\";\n}\n\n.fa-dedent:before,\n.fa-outdent:before {\n  content: \"\";\n}\n\n.fa-indent:before {\n  content: \"\";\n}\n\n.fa-video-camera:before {\n  content: \"\";\n}\n\n.fa-photo:before,\n.fa-image:before,\n.fa-picture-o:before {\n  content: \"\";\n}\n\n.fa-pencil:before {\n  content: \"\";\n}\n\n.fa-map-marker:before {\n  content: \"\";\n}\n\n.fa-adjust:before {\n  content: \"\";\n}\n\n.fa-tint:before {\n  content: \"\";\n}\n\n.fa-edit:before,\n.fa-pencil-square-o:before {\n  content: \"\";\n}\n\n.fa-share-square-o:before {\n  content: \"\";\n}\n\n.fa-check-square-o:before {\n  content: \"\";\n}\n\n.fa-arrows:before {\n  content: \"\";\n}\n\n.fa-step-backward:before {\n  content: \"\";\n}\n\n.fa-fast-backward:before {\n  content: \"\";\n}\n\n.fa-backward:before {\n  content: \"\";\n}\n\n.fa-play:before {\n  content: \"\";\n}\n\n.fa-pause:before {\n  content: \"\";\n}\n\n.fa-stop:before {\n  content: \"\";\n}\n\n.fa-forward:before {\n  content: \"\";\n}\n\n.fa-fast-forward:before {\n  content: \"\";\n}\n\n.fa-step-forward:before {\n  content: \"\";\n}\n\n.fa-eject:before {\n  content: \"\";\n}\n\n.fa-chevron-left:before {\n  content: \"\";\n}\n\n.fa-chevron-right:before {\n  content: \"\";\n}\n\n.fa-plus-circle:before {\n  content: \"\";\n}\n\n.fa-minus-circle:before {\n  content: \"\";\n}\n\n.fa-times-circle:before, .wy-inline-validate.wy-inline-validate-danger .wy-input-context:before {\n  content: \"\";\n}\n\n.fa-check-circle:before, .wy-inline-validate.wy-inline-validate-success .wy-input-context:before {\n  content: \"\";\n}\n\n.fa-question-circle:before {\n  content: \"\";\n}\n\n.fa-info-circle:before {\n  content: \"\";\n}\n\n.fa-crosshairs:before {\n  content: \"\";\n}\n\n.fa-times-circle-o:before {\n  content: \"\";\n}\n\n.fa-check-circle-o:before {\n  content: \"\";\n}\n\n.fa-ban:before {\n  content: \"\";\n}\n\n.fa-arrow-left:before {\n  content: \"\";\n}\n\n.fa-arrow-right:before {\n  content: \"\";\n}\n\n.fa-arrow-up:before {\n  content: \"\";\n}\n\n.fa-arrow-down:before {\n  content: \"\";\n}\n\n.fa-mail-forward:before,\n.fa-share:before {\n  content: \"\";\n}\n\n.fa-expand:before {\n  content: \"\";\n}\n\n.fa-compress:before {\n  content: \"\";\n}\n\n.fa-plus:before {\n  content: \"\";\n}\n\n.fa-minus:before {\n  content: \"\";\n}\n\n.fa-asterisk:before {\n  content: \"\";\n}\n\n.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 {\n  content: \"\";\n}\n\n.fa-gift:before {\n  content: \"\";\n}\n\n.fa-leaf:before {\n  content: \"\";\n}\n\n.fa-fire:before, .icon-fire:before {\n  content: \"\";\n}\n\n.fa-eye:before {\n  content: \"\";\n}\n\n.fa-eye-slash:before {\n  content: \"\";\n}\n\n.fa-warning:before,\n.fa-exclamation-triangle:before {\n  content: \"\";\n}\n\n.fa-plane:before {\n  content: \"\";\n}\n\n.fa-calendar:before {\n  content: \"\";\n}\n\n.fa-random:before {\n  content: \"\";\n}\n\n.fa-comment:before {\n  content: \"\";\n}\n\n.fa-magnet:before {\n  content: \"\";\n}\n\n.fa-chevron-up:before {\n  content: \"\";\n}\n\n.fa-chevron-down:before {\n  content: \"\";\n}\n\n.fa-retweet:before {\n  content: \"\";\n}\n\n.fa-shopping-cart:before {\n  content: \"\";\n}\n\n.fa-folder:before {\n  content: \"\";\n}\n\n.fa-folder-open:before {\n  content: \"\";\n}\n\n.fa-arrows-v:before {\n  content: \"\";\n}\n\n.fa-arrows-h:before {\n  content: \"\";\n}\n\n.fa-bar-chart-o:before,\n.fa-bar-chart:before {\n  content: \"\";\n}\n\n.fa-twitter-square:before {\n  content: \"\";\n}\n\n.fa-facebook-square:before {\n  content: \"\";\n}\n\n.fa-camera-retro:before {\n  content: \"\";\n}\n\n.fa-key:before {\n  content: \"\";\n}\n\n.fa-gears:before,\n.fa-cogs:before {\n  content: \"\";\n}\n\n.fa-comments:before {\n  content: \"\";\n}\n\n.fa-thumbs-o-up:before {\n  content: \"\";\n}\n\n.fa-thumbs-o-down:before {\n  content: \"\";\n}\n\n.fa-star-half:before {\n  content: \"\";\n}\n\n.fa-heart-o:before {\n  content: \"\";\n}\n\n.fa-sign-out:before {\n  content: \"\";\n}\n\n.fa-linkedin-square:before {\n  content: \"\";\n}\n\n.fa-thumb-tack:before {\n  content: \"\";\n}\n\n.fa-external-link:before {\n  content: \"\";\n}\n\n.fa-sign-in:before {\n  content: \"\";\n}\n\n.fa-trophy:before {\n  content: \"\";\n}\n\n.fa-github-square:before {\n  content: \"\";\n}\n\n.fa-upload:before {\n  content: \"\";\n}\n\n.fa-lemon-o:before {\n  content: \"\";\n}\n\n.fa-phone:before {\n  content: \"\";\n}\n\n.fa-square-o:before {\n  content: \"\";\n}\n\n.fa-bookmark-o:before {\n  content: \"\";\n}\n\n.fa-phone-square:before {\n  content: \"\";\n}\n\n.fa-twitter:before {\n  content: \"\";\n}\n\n.fa-facebook:before {\n  content: \"\";\n}\n\n.fa-github:before, .icon-github:before {\n  content: \"\";\n}\n\n.fa-unlock:before {\n  content: \"\";\n}\n\n.fa-credit-card:before {\n  content: \"\";\n}\n\n.fa-rss:before {\n  content: \"\";\n}\n\n.fa-hdd-o:before {\n  content: \"\";\n}\n\n.fa-bullhorn:before {\n  content: \"\";\n}\n\n.fa-bell:before {\n  content: \"\";\n}\n\n.fa-certificate:before {\n  content: \"\";\n}\n\n.fa-hand-o-right:before {\n  content: \"\";\n}\n\n.fa-hand-o-left:before {\n  content: \"\";\n}\n\n.fa-hand-o-up:before {\n  content: \"\";\n}\n\n.fa-hand-o-down:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-left:before, .icon-circle-arrow-left:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-right:before, .icon-circle-arrow-right:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-up:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-down:before {\n  content: \"\";\n}\n\n.fa-globe:before {\n  content: \"\";\n}\n\n.fa-wrench:before {\n  content: \"\";\n}\n\n.fa-tasks:before {\n  content: \"\";\n}\n\n.fa-filter:before {\n  content: \"\";\n}\n\n.fa-briefcase:before {\n  content: \"\";\n}\n\n.fa-arrows-alt:before {\n  content: \"\";\n}\n\n.fa-group:before,\n.fa-users:before {\n  content: \"\";\n}\n\n.fa-chain:before,\n.fa-link:before,\n.icon-link:before {\n  content: \"\";\n}\n\n.fa-cloud:before {\n  content: \"\";\n}\n\n.fa-flask:before {\n  content: \"\";\n}\n\n.fa-cut:before,\n.fa-scissors:before {\n  content: \"\";\n}\n\n.fa-copy:before,\n.fa-files-o:before {\n  content: \"\";\n}\n\n.fa-paperclip:before {\n  content: \"\";\n}\n\n.fa-save:before,\n.fa-floppy-o:before {\n  content: \"\";\n}\n\n.fa-square:before {\n  content: \"\";\n}\n\n.fa-navicon:before,\n.fa-reorder:before,\n.fa-bars:before {\n  content: \"\";\n}\n\n.fa-list-ul:before {\n  content: \"\";\n}\n\n.fa-list-ol:before {\n  content: \"\";\n}\n\n.fa-strikethrough:before {\n  content: \"\";\n}\n\n.fa-underline:before {\n  content: \"\";\n}\n\n.fa-table:before {\n  content: \"\";\n}\n\n.fa-magic:before {\n  content: \"\";\n}\n\n.fa-truck:before {\n  content: \"\";\n}\n\n.fa-pinterest:before {\n  content: \"\";\n}\n\n.fa-pinterest-square:before {\n  content: \"\";\n}\n\n.fa-google-plus-square:before {\n  content: \"\";\n}\n\n.fa-google-plus:before {\n  content: \"\";\n}\n\n.fa-money:before {\n  content: \"\";\n}\n\n.fa-caret-down:before, .wy-dropdown .caret:before, .icon-caret-down:before {\n  content: \"\";\n}\n\n.fa-caret-up:before {\n  content: \"\";\n}\n\n.fa-caret-left:before {\n  content: \"\";\n}\n\n.fa-caret-right:before {\n  content: \"\";\n}\n\n.fa-columns:before {\n  content: \"\";\n}\n\n.fa-unsorted:before,\n.fa-sort:before {\n  content: \"\";\n}\n\n.fa-sort-down:before,\n.fa-sort-desc:before {\n  content: \"\";\n}\n\n.fa-sort-up:before,\n.fa-sort-asc:before {\n  content: \"\";\n}\n\n.fa-envelope:before {\n  content: \"\";\n}\n\n.fa-linkedin:before {\n  content: \"\";\n}\n\n.fa-rotate-left:before,\n.fa-undo:before {\n  content: \"\";\n}\n\n.fa-legal:before,\n.fa-gavel:before {\n  content: \"\";\n}\n\n.fa-dashboard:before,\n.fa-tachometer:before {\n  content: \"\";\n}\n\n.fa-comment-o:before {\n  content: \"\";\n}\n\n.fa-comments-o:before {\n  content: \"\";\n}\n\n.fa-flash:before,\n.fa-bolt:before {\n  content: \"\";\n}\n\n.fa-sitemap:before {\n  content: \"\";\n}\n\n.fa-umbrella:before {\n  content: \"\";\n}\n\n.fa-paste:before,\n.fa-clipboard:before {\n  content: \"\";\n}\n\n.fa-lightbulb-o:before {\n  content: \"\";\n}\n\n.fa-exchange:before {\n  content: \"\";\n}\n\n.fa-cloud-download:before {\n  content: \"\";\n}\n\n.fa-cloud-upload:before {\n  content: \"\";\n}\n\n.fa-user-md:before {\n  content: \"\";\n}\n\n.fa-stethoscope:before {\n  content: \"\";\n}\n\n.fa-suitcase:before {\n  content: \"\";\n}\n\n.fa-bell-o:before {\n  content: \"\";\n}\n\n.fa-coffee:before {\n  content: \"\";\n}\n\n.fa-cutlery:before {\n  content: \"\";\n}\n\n.fa-file-text-o:before {\n  content: \"\";\n}\n\n.fa-building-o:before {\n  content: \"\";\n}\n\n.fa-hospital-o:before {\n  content: \"\";\n}\n\n.fa-ambulance:before {\n  content: \"\";\n}\n\n.fa-medkit:before {\n  content: \"\";\n}\n\n.fa-fighter-jet:before {\n  content: \"\";\n}\n\n.fa-beer:before {\n  content: \"\";\n}\n\n.fa-h-square:before {\n  content: \"\";\n}\n\n.fa-plus-square:before {\n  content: \"\";\n}\n\n.fa-angle-double-left:before {\n  content: \"\";\n}\n\n.fa-angle-double-right:before {\n  content: \"\";\n}\n\n.fa-angle-double-up:before {\n  content: \"\";\n}\n\n.fa-angle-double-down:before {\n  content: \"\";\n}\n\n.fa-angle-left:before {\n  content: \"\";\n}\n\n.fa-angle-right:before {\n  content: \"\";\n}\n\n.fa-angle-up:before {\n  content: \"\";\n}\n\n.fa-angle-down:before {\n  content: \"\";\n}\n\n.fa-desktop:before {\n  content: \"\";\n}\n\n.fa-laptop:before {\n  content: \"\";\n}\n\n.fa-tablet:before {\n  content: \"\";\n}\n\n.fa-mobile-phone:before,\n.fa-mobile:before {\n  content: \"\";\n}\n\n.fa-circle-o:before {\n  content: \"\";\n}\n\n.fa-quote-left:before {\n  content: \"\";\n}\n\n.fa-quote-right:before {\n  content: \"\";\n}\n\n.fa-spinner:before {\n  content: \"\";\n}\n\n.fa-circle:before {\n  content: \"\";\n}\n\n.fa-mail-reply:before,\n.fa-reply:before {\n  content: \"\";\n}\n\n.fa-github-alt:before {\n  content: \"\";\n}\n\n.fa-folder-o:before {\n  content: \"\";\n}\n\n.fa-folder-open-o:before {\n  content: \"\";\n}\n\n.fa-smile-o:before {\n  content: \"\";\n}\n\n.fa-frown-o:before {\n  content: \"\";\n}\n\n.fa-meh-o:before {\n  content: \"\";\n}\n\n.fa-gamepad:before {\n  content: \"\";\n}\n\n.fa-keyboard-o:before {\n  content: \"\";\n}\n\n.fa-flag-o:before {\n  content: \"\";\n}\n\n.fa-flag-checkered:before {\n  content: \"\";\n}\n\n.fa-terminal:before {\n  content: \"\";\n}\n\n.fa-code:before {\n  content: \"\";\n}\n\n.fa-mail-reply-all:before,\n.fa-reply-all:before {\n  content: \"\";\n}\n\n.fa-star-half-empty:before,\n.fa-star-half-full:before,\n.fa-star-half-o:before {\n  content: \"\";\n}\n\n.fa-location-arrow:before {\n  content: \"\";\n}\n\n.fa-crop:before {\n  content: \"\";\n}\n\n.fa-code-fork:before {\n  content: \"\";\n}\n\n.fa-unlink:before,\n.fa-chain-broken:before {\n  content: \"\";\n}\n\n.fa-question:before {\n  content: \"\";\n}\n\n.fa-info:before {\n  content: \"\";\n}\n\n.fa-exclamation:before {\n  content: \"\";\n}\n\n.fa-superscript:before {\n  content: \"\";\n}\n\n.fa-subscript:before {\n  content: \"\";\n}\n\n.fa-eraser:before {\n  content: \"\";\n}\n\n.fa-puzzle-piece:before {\n  content: \"\";\n}\n\n.fa-microphone:before {\n  content: \"\";\n}\n\n.fa-microphone-slash:before {\n  content: \"\";\n}\n\n.fa-shield:before {\n  content: \"\";\n}\n\n.fa-calendar-o:before {\n  content: \"\";\n}\n\n.fa-fire-extinguisher:before {\n  content: \"\";\n}\n\n.fa-rocket:before {\n  content: \"\";\n}\n\n.fa-maxcdn:before {\n  content: \"\";\n}\n\n.fa-chevron-circle-left:before {\n  content: \"\";\n}\n\n.fa-chevron-circle-right:before {\n  content: \"\";\n}\n\n.fa-chevron-circle-up:before {\n  content: \"\";\n}\n\n.fa-chevron-circle-down:before {\n  content: \"\";\n}\n\n.fa-html5:before {\n  content: \"\";\n}\n\n.fa-css3:before {\n  content: \"\";\n}\n\n.fa-anchor:before {\n  content: \"\";\n}\n\n.fa-unlock-alt:before {\n  content: \"\";\n}\n\n.fa-bullseye:before {\n  content: \"\";\n}\n\n.fa-ellipsis-h:before {\n  content: \"\";\n}\n\n.fa-ellipsis-v:before {\n  content: \"\";\n}\n\n.fa-rss-square:before {\n  content: \"\";\n}\n\n.fa-play-circle:before {\n  content: \"\";\n}\n\n.fa-ticket:before {\n  content: \"\";\n}\n\n.fa-minus-square:before {\n  content: \"\";\n}\n\n.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 {\n  content: \"\";\n}\n\n.fa-level-up:before {\n  content: \"\";\n}\n\n.fa-level-down:before {\n  content: \"\";\n}\n\n.fa-check-square:before {\n  content: \"\";\n}\n\n.fa-pencil-square:before {\n  content: \"\";\n}\n\n.fa-external-link-square:before {\n  content: \"\";\n}\n\n.fa-share-square:before {\n  content: \"\";\n}\n\n.fa-compass:before {\n  content: \"\";\n}\n\n.fa-toggle-down:before,\n.fa-caret-square-o-down:before {\n  content: \"\";\n}\n\n.fa-toggle-up:before,\n.fa-caret-square-o-up:before {\n  content: \"\";\n}\n\n.fa-toggle-right:before,\n.fa-caret-square-o-right:before {\n  content: \"\";\n}\n\n.fa-euro:before,\n.fa-eur:before {\n  content: \"\";\n}\n\n.fa-gbp:before {\n  content: \"\";\n}\n\n.fa-dollar:before,\n.fa-usd:before {\n  content: \"\";\n}\n\n.fa-rupee:before,\n.fa-inr:before {\n  content: \"\";\n}\n\n.fa-cny:before,\n.fa-rmb:before,\n.fa-yen:before,\n.fa-jpy:before {\n  content: \"\";\n}\n\n.fa-ruble:before,\n.fa-rouble:before,\n.fa-rub:before {\n  content: \"\";\n}\n\n.fa-won:before,\n.fa-krw:before {\n  content: \"\";\n}\n\n.fa-bitcoin:before,\n.fa-btc:before {\n  content: \"\";\n}\n\n.fa-file:before {\n  content: \"\";\n}\n\n.fa-file-text:before {\n  content: \"\";\n}\n\n.fa-sort-alpha-asc:before {\n  content: \"\";\n}\n\n.fa-sort-alpha-desc:before {\n  content: \"\";\n}\n\n.fa-sort-amount-asc:before {\n  content: \"\";\n}\n\n.fa-sort-amount-desc:before {\n  content: \"\";\n}\n\n.fa-sort-numeric-asc:before {\n  content: \"\";\n}\n\n.fa-sort-numeric-desc:before {\n  content: \"\";\n}\n\n.fa-thumbs-up:before {\n  content: \"\";\n}\n\n.fa-thumbs-down:before {\n  content: \"\";\n}\n\n.fa-youtube-square:before {\n  content: \"\";\n}\n\n.fa-youtube:before {\n  content: \"\";\n}\n\n.fa-xing:before {\n  content: \"\";\n}\n\n.fa-xing-square:before {\n  content: \"\";\n}\n\n.fa-youtube-play:before {\n  content: \"\";\n}\n\n.fa-dropbox:before {\n  content: \"\";\n}\n\n.fa-stack-overflow:before {\n  content: \"\";\n}\n\n.fa-instagram:before {\n  content: \"\";\n}\n\n.fa-flickr:before {\n  content: \"\";\n}\n\n.fa-adn:before {\n  content: \"\";\n}\n\n.fa-bitbucket:before, .icon-bitbucket:before {\n  content: \"\";\n}\n\n.fa-bitbucket-square:before {\n  content: \"\";\n}\n\n.fa-tumblr:before {\n  content: \"\";\n}\n\n.fa-tumblr-square:before {\n  content: \"\";\n}\n\n.fa-long-arrow-down:before {\n  content: \"\";\n}\n\n.fa-long-arrow-up:before {\n  content: \"\";\n}\n\n.fa-long-arrow-left:before {\n  content: \"\";\n}\n\n.fa-long-arrow-right:before {\n  content: \"\";\n}\n\n.fa-apple:before {\n  content: \"\";\n}\n\n.fa-windows:before {\n  content: \"\";\n}\n\n.fa-android:before {\n  content: \"\";\n}\n\n.fa-linux:before {\n  content: \"\";\n}\n\n.fa-dribbble:before {\n  content: \"\";\n}\n\n.fa-skype:before {\n  content: \"\";\n}\n\n.fa-foursquare:before {\n  content: \"\";\n}\n\n.fa-trello:before {\n  content: \"\";\n}\n\n.fa-female:before {\n  content: \"\";\n}\n\n.fa-male:before {\n  content: \"\";\n}\n\n.fa-gittip:before {\n  content: \"\";\n}\n\n.fa-sun-o:before {\n  content: \"\";\n}\n\n.fa-moon-o:before {\n  content: \"\";\n}\n\n.fa-archive:before {\n  content: \"\";\n}\n\n.fa-bug:before {\n  content: \"\";\n}\n\n.fa-vk:before {\n  content: \"\";\n}\n\n.fa-weibo:before {\n  content: \"\";\n}\n\n.fa-renren:before {\n  content: \"\";\n}\n\n.fa-pagelines:before {\n  content: \"\";\n}\n\n.fa-stack-exchange:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-o-right:before {\n  content: \"\";\n}\n\n.fa-arrow-circle-o-left:before {\n  content: \"\";\n}\n\n.fa-toggle-left:before,\n.fa-caret-square-o-left:before {\n  content: \"\";\n}\n\n.fa-dot-circle-o:before {\n  content: \"\";\n}\n\n.fa-wheelchair:before {\n  content: \"\";\n}\n\n.fa-vimeo-square:before {\n  content: \"\";\n}\n\n.fa-turkish-lira:before,\n.fa-try:before {\n  content: \"\";\n}\n\n.fa-plus-square-o:before, .wy-menu-vertical li span.toctree-expand:before {\n  content: \"\";\n}\n\n.fa-space-shuttle:before {\n  content: \"\";\n}\n\n.fa-slack:before {\n  content: \"\";\n}\n\n.fa-envelope-square:before {\n  content: \"\";\n}\n\n.fa-wordpress:before {\n  content: \"\";\n}\n\n.fa-openid:before {\n  content: \"\";\n}\n\n.fa-institution:before,\n.fa-bank:before,\n.fa-university:before {\n  content: \"\";\n}\n\n.fa-mortar-board:before,\n.fa-graduation-cap:before {\n  content: \"\";\n}\n\n.fa-yahoo:before {\n  content: \"\";\n}\n\n.fa-google:before {\n  content: \"\";\n}\n\n.fa-reddit:before {\n  content: \"\";\n}\n\n.fa-reddit-square:before {\n  content: \"\";\n}\n\n.fa-stumbleupon-circle:before {\n  content: \"\";\n}\n\n.fa-stumbleupon:before {\n  content: \"\";\n}\n\n.fa-delicious:before {\n  content: \"\";\n}\n\n.fa-digg:before {\n  content: \"\";\n}\n\n.fa-pied-piper:before {\n  content: \"\";\n}\n\n.fa-pied-piper-alt:before {\n  content: \"\";\n}\n\n.fa-drupal:before {\n  content: \"\";\n}\n\n.fa-joomla:before {\n  content: \"\";\n}\n\n.fa-language:before {\n  content: \"\";\n}\n\n.fa-fax:before {\n  content: \"\";\n}\n\n.fa-building:before {\n  content: \"\";\n}\n\n.fa-child:before {\n  content: \"\";\n}\n\n.fa-paw:before {\n  content: \"\";\n}\n\n.fa-spoon:before {\n  content: \"\";\n}\n\n.fa-cube:before {\n  content: \"\";\n}\n\n.fa-cubes:before {\n  content: \"\";\n}\n\n.fa-behance:before {\n  content: \"\";\n}\n\n.fa-behance-square:before {\n  content: \"\";\n}\n\n.fa-steam:before {\n  content: \"\";\n}\n\n.fa-steam-square:before {\n  content: \"\";\n}\n\n.fa-recycle:before {\n  content: \"\";\n}\n\n.fa-automobile:before,\n.fa-car:before {\n  content: \"\";\n}\n\n.fa-cab:before,\n.fa-taxi:before {\n  content: \"\";\n}\n\n.fa-tree:before {\n  content: \"\";\n}\n\n.fa-spotify:before {\n  content: \"\";\n}\n\n.fa-deviantart:before {\n  content: \"\";\n}\n\n.fa-soundcloud:before {\n  content: \"\";\n}\n\n.fa-database:before {\n  content: \"\";\n}\n\n.fa-file-pdf-o:before {\n  content: \"\";\n}\n\n.fa-file-word-o:before {\n  content: \"\";\n}\n\n.fa-file-excel-o:before {\n  content: \"\";\n}\n\n.fa-file-powerpoint-o:before {\n  content: \"\";\n}\n\n.fa-file-photo-o:before,\n.fa-file-picture-o:before,\n.fa-file-image-o:before {\n  content: \"\";\n}\n\n.fa-file-zip-o:before,\n.fa-file-archive-o:before {\n  content: \"\";\n}\n\n.fa-file-sound-o:before,\n.fa-file-audio-o:before {\n  content: \"\";\n}\n\n.fa-file-movie-o:before,\n.fa-file-video-o:before {\n  content: \"\";\n}\n\n.fa-file-code-o:before {\n  content: \"\";\n}\n\n.fa-vine:before {\n  content: \"\";\n}\n\n.fa-codepen:before {\n  content: \"\";\n}\n\n.fa-jsfiddle:before {\n  content: \"\";\n}\n\n.fa-life-bouy:before,\n.fa-life-buoy:before,\n.fa-life-saver:before,\n.fa-support:before,\n.fa-life-ring:before {\n  content: \"\";\n}\n\n.fa-circle-o-notch:before {\n  content: \"\";\n}\n\n.fa-ra:before,\n.fa-rebel:before {\n  content: \"\";\n}\n\n.fa-ge:before,\n.fa-empire:before {\n  content: \"\";\n}\n\n.fa-git-square:before {\n  content: \"\";\n}\n\n.fa-git:before {\n  content: \"\";\n}\n\n.fa-hacker-news:before {\n  content: \"\";\n}\n\n.fa-tencent-weibo:before {\n  content: \"\";\n}\n\n.fa-qq:before {\n  content: \"\";\n}\n\n.fa-wechat:before,\n.fa-weixin:before {\n  content: \"\";\n}\n\n.fa-send:before,\n.fa-paper-plane:before {\n  content: \"\";\n}\n\n.fa-send-o:before,\n.fa-paper-plane-o:before {\n  content: \"\";\n}\n\n.fa-history:before {\n  content: \"\";\n}\n\n.fa-circle-thin:before {\n  content: \"\";\n}\n\n.fa-header:before {\n  content: \"\";\n}\n\n.fa-paragraph:before {\n  content: \"\";\n}\n\n.fa-sliders:before {\n  content: \"\";\n}\n\n.fa-share-alt:before {\n  content: \"\";\n}\n\n.fa-share-alt-square:before {\n  content: \"\";\n}\n\n.fa-bomb:before {\n  content: \"\";\n}\n\n.fa-soccer-ball-o:before,\n.fa-futbol-o:before {\n  content: \"\";\n}\n\n.fa-tty:before {\n  content: \"\";\n}\n\n.fa-binoculars:before {\n  content: \"\";\n}\n\n.fa-plug:before {\n  content: \"\";\n}\n\n.fa-slideshare:before {\n  content: \"\";\n}\n\n.fa-twitch:before {\n  content: \"\";\n}\n\n.fa-yelp:before {\n  content: \"\";\n}\n\n.fa-newspaper-o:before {\n  content: \"\";\n}\n\n.fa-wifi:before {\n  content: \"\";\n}\n\n.fa-calculator:before {\n  content: \"\";\n}\n\n.fa-paypal:before {\n  content: \"\";\n}\n\n.fa-google-wallet:before {\n  content: \"\";\n}\n\n.fa-cc-visa:before {\n  content: \"\";\n}\n\n.fa-cc-mastercard:before {\n  content: \"\";\n}\n\n.fa-cc-discover:before {\n  content: \"\";\n}\n\n.fa-cc-amex:before {\n  content: \"\";\n}\n\n.fa-cc-paypal:before {\n  content: \"\";\n}\n\n.fa-cc-stripe:before {\n  content: \"\";\n}\n\n.fa-bell-slash:before {\n  content: \"\";\n}\n\n.fa-bell-slash-o:before {\n  content: \"\";\n}\n\n.fa-trash:before {\n  content: \"\";\n}\n\n.fa-copyright:before {\n  content: \"\";\n}\n\n.fa-at:before {\n  content: \"\";\n}\n\n.fa-eyedropper:before {\n  content: \"\";\n}\n\n.fa-paint-brush:before {\n  content: \"\";\n}\n\n.fa-birthday-cake:before {\n  content: \"\";\n}\n\n.fa-area-chart:before {\n  content: \"\";\n}\n\n.fa-pie-chart:before {\n  content: \"\";\n}\n\n.fa-line-chart:before {\n  content: \"\";\n}\n\n.fa-lastfm:before {\n  content: \"\";\n}\n\n.fa-lastfm-square:before {\n  content: \"\";\n}\n\n.fa-toggle-off:before {\n  content: \"\";\n}\n\n.fa-toggle-on:before {\n  content: \"\";\n}\n\n.fa-bicycle:before {\n  content: \"\";\n}\n\n.fa-bus:before {\n  content: \"\";\n}\n\n.fa-ioxhost:before {\n  content: \"\";\n}\n\n.fa-angellist:before {\n  content: \"\";\n}\n\n.fa-cc:before {\n  content: \"\";\n}\n\n.fa-shekel:before,\n.fa-sheqel:before,\n.fa-ils:before {\n  content: \"\";\n}\n\n.fa-meanpath:before {\n  content: \"\";\n}\n\n.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 {\n  font-family: inherit;\n}\n.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 {\n  font-family: \"FontAwesome\";\n  display: inline-block;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  text-decoration: inherit;\n}\n\na .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 {\n  display: inline-block;\n  text-decoration: inherit;\n}\n\n.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 {\n  display: inline;\n}\n.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 {\n  line-height: 0.9em;\n}\n.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 {\n  display: inline-block;\n}\n\n.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 {\n  opacity: 0.5;\n  -webkit-transition: opacity 0.05s ease-in;\n  -moz-transition: opacity 0.05s ease-in;\n  transition: opacity 0.05s ease-in;\n}\n\n.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 {\n  opacity: 1;\n}\n\n.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 {\n  font-size: 14px;\n  vertical-align: -15%;\n}\n\n.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 {\n  padding: 12px;\n  line-height: 24px;\n  margin-bottom: 24px;\n  background: #e2effd;\n}\n\n.wy-alert-title, .rst-content .admonition-title {\n  color: #fff;\n  font-weight: bold;\n  display: block;\n  color: #fff;\n  background: #53a2f4;\n  margin: -12px;\n  padding: 6px 12px;\n  margin-bottom: 12px;\n}\n\n.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 {\n  background: #fdf3f2;\n}\n.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 {\n  background: #f29f97;\n}\n\n.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 {\n  background: #ffedcc;\n}\n.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 {\n  background: #f0b37e;\n}\n\n.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 {\n  background: #e2effd;\n}\n.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 {\n  background: #53a2f4;\n}\n\n.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 {\n  background: #dbfaf4;\n}\n.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 {\n  background: #1abc9c;\n}\n\n.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 {\n  background: #f3f6f6;\n}\n.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 {\n  color: #404040;\n  background: #e1e4e5;\n}\n.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 {\n  color: #0E6FD2;\n}\n\n.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 {\n  margin-bottom: 0;\n}\n\n.wy-tray-container {\n  position: fixed;\n  bottom: 0px;\n  left: 0;\n  z-index: 600;\n}\n.wy-tray-container li {\n  display: block;\n  width: 300px;\n  background: transparent;\n  color: #fff;\n  text-align: center;\n  box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.1);\n  padding: 0 24px;\n  min-width: 20%;\n  opacity: 0;\n  height: 0;\n  line-height: 56px;\n  overflow: hidden;\n  -webkit-transition: all 0.3s ease-in;\n  -moz-transition: all 0.3s ease-in;\n  transition: all 0.3s ease-in;\n}\n.wy-tray-container li.wy-tray-item-success {\n  background: #27AE60;\n}\n.wy-tray-container li.wy-tray-item-info {\n  background: #0E6FD2;\n}\n.wy-tray-container li.wy-tray-item-warning {\n  background: #E67E22;\n}\n.wy-tray-container li.wy-tray-item-danger {\n  background: #E74C3C;\n}\n.wy-tray-container li.on {\n  opacity: 1;\n  height: 56px;\n}\n\n@media screen and (max-width: 768px) {\n  .wy-tray-container {\n    bottom: auto;\n    top: 0;\n    width: 100%;\n  }\n  .wy-tray-container li {\n    width: 100%;\n  }\n}\nbutton {\n  font-size: 100%;\n  margin: 0;\n  vertical-align: baseline;\n  *vertical-align: middle;\n  cursor: pointer;\n  line-height: normal;\n  -webkit-appearance: button;\n  *overflow: visible;\n}\n\nbutton::-moz-focus-inner, input::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\nbutton[disabled] {\n  cursor: default;\n}\n\n.btn {\n  /* Structure */\n  display: inline-block;\n  border-radius: 2px;\n  line-height: normal;\n  white-space: nowrap;\n  text-align: center;\n  cursor: pointer;\n  font-size: 100%;\n  padding: 6px 12px 8px 12px;\n  color: #fff;\n  border: 1px solid rgba(0, 0, 0, 0.1);\n  background-color: #27AE60;\n  text-decoration: none;\n  font-weight: normal;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  box-shadow: 0px 1px 2px -1px rgba(255, 255, 255, 0.5) inset, 0px -2px 0px 0px rgba(0, 0, 0, 0.1) inset;\n  outline-none: false;\n  vertical-align: middle;\n  *display: inline;\n  zoom: 1;\n  -webkit-user-drag: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  -webkit-transition: all 0.1s linear;\n  -moz-transition: all 0.1s linear;\n  transition: all 0.1s linear;\n}\n\n.btn-hover {\n  background: #107cea;\n  color: #fff;\n}\n\n.btn:hover {\n  background: #2cc36b;\n  color: #fff;\n}\n.btn:focus {\n  background: #2cc36b;\n  outline: 0;\n}\n.btn:active {\n  box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.05) inset, 0px 2px 0px 0px rgba(0, 0, 0, 0.1) inset;\n  padding: 8px 12px 6px 12px;\n}\n.btn:visited {\n  color: #fff;\n}\n.btn:disabled {\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  filter: alpha(opacity=40);\n  opacity: 0.4;\n  cursor: not-allowed;\n  box-shadow: none;\n}\n\n.btn-disabled {\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  filter: alpha(opacity=40);\n  opacity: 0.4;\n  cursor: not-allowed;\n  box-shadow: none;\n}\n.btn-disabled:hover, .btn-disabled:focus, .btn-disabled:active {\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  filter: alpha(opacity=40);\n  opacity: 0.4;\n  cursor: not-allowed;\n  box-shadow: none;\n}\n\n.btn::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\n\n.btn-small {\n  font-size: 80%;\n}\n\n.btn-info {\n  background-color: #0E6FD2 !important;\n}\n.btn-info:hover {\n  background-color: #107cea !important;\n}\n\n.btn-neutral {\n  background-color: #f3f6f6 !important;\n  color: #404040 !important;\n}\n.btn-neutral:hover {\n  background-color: #e5ebeb !important;\n  color: #404040;\n}\n.btn-neutral:visited {\n  color: #404040 !important;\n}\n\n.btn-success {\n  background-color: #27AE60 !important;\n}\n.btn-success:hover {\n  background-color: #229955 !important;\n}\n\n.btn-danger {\n  background-color: #E74C3C !important;\n}\n.btn-danger:hover {\n  background-color: #ea6153 !important;\n}\n\n.btn-warning {\n  background-color: #E67E22 !important;\n}\n.btn-warning:hover {\n  background-color: #e98b39 !important;\n}\n\n.btn-invert {\n  background-color: #222;\n}\n.btn-invert:hover {\n  background-color: #2f2f2f !important;\n}\n\n.btn-link {\n  background-color: transparent !important;\n  color: #0E6FD2;\n  box-shadow: none;\n  border-color: transparent !important;\n}\n.btn-link:hover {\n  background-color: transparent !important;\n  color: #2388f0 !important;\n  box-shadow: none;\n}\n.btn-link:active {\n  background-color: transparent !important;\n  color: #2388f0 !important;\n  box-shadow: none;\n}\n.btn-link:visited {\n  color: #9B59B6;\n}\n\n.wy-btn-group .btn, .wy-control .btn {\n  vertical-align: middle;\n}\n\n.wy-btn-group {\n  margin-bottom: 24px;\n  *zoom: 1;\n}\n.wy-btn-group:before, .wy-btn-group:after {\n  display: table;\n  content: \"\";\n}\n.wy-btn-group:after {\n  clear: both;\n}\n\n.wy-dropdown {\n  position: relative;\n  display: inline-block;\n}\n\n.wy-dropdown-active .wy-dropdown-menu {\n  display: block;\n}\n\n.wy-dropdown-menu {\n  position: absolute;\n  left: 0;\n  display: none;\n  float: left;\n  top: 100%;\n  min-width: 100%;\n  background: #fcfcfc;\n  z-index: 100;\n  border: solid 1px #cfd7dd;\n  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1);\n  padding: 12px;\n}\n.wy-dropdown-menu > dd > a {\n  display: block;\n  clear: both;\n  color: #404040;\n  white-space: nowrap;\n  font-size: 90%;\n  padding: 0 12px;\n  cursor: pointer;\n}\n.wy-dropdown-menu > dd > a:hover {\n  background: #0E6FD2;\n  color: #fff;\n}\n.wy-dropdown-menu > dd.divider {\n  border-top: solid 1px #cfd7dd;\n  margin: 6px 0;\n}\n.wy-dropdown-menu > dd.search {\n  padding-bottom: 12px;\n}\n.wy-dropdown-menu > dd.search input[type=\"search\"] {\n  width: 100%;\n}\n.wy-dropdown-menu > dd.call-to-action {\n  background: #e3e3e3;\n  text-transform: uppercase;\n  font-weight: 500;\n  font-size: 80%;\n}\n.wy-dropdown-menu > dd.call-to-action:hover {\n  background: #e3e3e3;\n}\n.wy-dropdown-menu > dd.call-to-action .btn {\n  color: #fff;\n}\n\n.wy-dropdown.wy-dropdown-up .wy-dropdown-menu {\n  bottom: 100%;\n  top: auto;\n  left: auto;\n  right: 0;\n}\n\n.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu {\n  background: #fcfcfc;\n  margin-top: 2px;\n}\n.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a {\n  padding: 6px 12px;\n}\n.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover {\n  background: #0E6FD2;\n  color: #fff;\n}\n\n.wy-dropdown.wy-dropdown-left .wy-dropdown-menu {\n  right: 0;\n  left: auto;\n  text-align: right;\n}\n\n.wy-dropdown-arrow:before {\n  content: \" \";\n  border-bottom: 5px solid whitesmoke;\n  border-left: 5px solid transparent;\n  border-right: 5px solid transparent;\n  position: absolute;\n  display: block;\n  top: -4px;\n  left: 50%;\n  margin-left: -3px;\n}\n.wy-dropdown-arrow.wy-dropdown-arrow-left:before {\n  left: 11px;\n}\n\n.wy-form-stacked select {\n  display: block;\n}\n\n.wy-form-aligned input, .wy-form-aligned textarea, .wy-form-aligned select, .wy-form-aligned .wy-help-inline, .wy-form-aligned label {\n  display: inline-block;\n  *display: inline;\n  *zoom: 1;\n  vertical-align: middle;\n}\n\n.wy-form-aligned .wy-control-group > label {\n  display: inline-block;\n  vertical-align: middle;\n  width: 10em;\n  margin: 6px 12px 0 0;\n  float: left;\n}\n.wy-form-aligned .wy-control {\n  float: left;\n}\n.wy-form-aligned .wy-control label {\n  display: block;\n}\n.wy-form-aligned .wy-control select {\n  margin-top: 6px;\n}\n\nfieldset {\n  border: 0;\n  margin: 0;\n  padding: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  border: 0;\n  padding: 0;\n  white-space: normal;\n  margin-bottom: 24px;\n  font-size: 150%;\n  *margin-left: -7px;\n}\n\nlabel {\n  display: block;\n  margin: 0 0 0.3125em 0;\n  color: #333;\n  font-size: 90%;\n}\n\ninput, select, textarea {\n  font-size: 100%;\n  margin: 0;\n  vertical-align: baseline;\n  *vertical-align: middle;\n}\n\n.wy-control-group {\n  margin-bottom: 24px;\n  *zoom: 1;\n  max-width: 68em;\n  margin-left: auto;\n  margin-right: auto;\n  *zoom: 1;\n}\n.wy-control-group:before, .wy-control-group:after {\n  display: table;\n  content: \"\";\n}\n.wy-control-group:after {\n  clear: both;\n}\n.wy-control-group:before, .wy-control-group:after {\n  display: table;\n  content: \"\";\n}\n.wy-control-group:after {\n  clear: both;\n}\n\n.wy-control-group.wy-control-group-required > label:after {\n  content: \" *\";\n  color: #E74C3C;\n}\n\n.wy-control-group .wy-form-full, .wy-control-group .wy-form-halves, .wy-control-group .wy-form-thirds {\n  padding-bottom: 12px;\n}\n.wy-control-group .wy-form-full select, .wy-control-group .wy-form-halves select, .wy-control-group .wy-form-thirds select {\n  width: 100%;\n}\n.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\"] {\n  width: 100%;\n}\n\n.wy-control-group .wy-form-full {\n  float: left;\n  display: block;\n  margin-right: 2.35765%;\n  width: 100%;\n  margin-right: 0;\n}\n.wy-control-group .wy-form-full:last-child {\n  margin-right: 0;\n}\n\n.wy-control-group .wy-form-halves {\n  float: left;\n  display: block;\n  margin-right: 2.35765%;\n  width: 48.82117%;\n}\n.wy-control-group .wy-form-halves:last-child {\n  margin-right: 0;\n}\n.wy-control-group .wy-form-halves:nth-of-type(2n) {\n  margin-right: 0;\n}\n.wy-control-group .wy-form-halves:nth-of-type(2n+1) {\n  clear: left;\n}\n\n.wy-control-group .wy-form-thirds {\n  float: left;\n  display: block;\n  margin-right: 2.35765%;\n  width: 31.76157%;\n}\n.wy-control-group .wy-form-thirds:last-child {\n  margin-right: 0;\n}\n.wy-control-group .wy-form-thirds:nth-of-type(3n) {\n  margin-right: 0;\n}\n.wy-control-group .wy-form-thirds:nth-of-type(3n+1) {\n  clear: left;\n}\n\n.wy-control-group.wy-control-group-no-input .wy-control {\n  margin: 6px 0 0 0;\n  font-size: 90%;\n}\n\n.wy-control-no-input {\n  display: inline-block;\n  margin: 6px 0 0 0;\n  font-size: 90%;\n}\n\n.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\"] {\n  width: 100%;\n}\n\n.wy-form-message-inline {\n  display: inline-block;\n  padding-left: 0.3em;\n  color: #666;\n  vertical-align: middle;\n  font-size: 90%;\n}\n\n.wy-form-message {\n  display: block;\n  color: #999;\n  font-size: 70%;\n  margin-top: 0.3125em;\n  font-style: italic;\n}\n.wy-form-message p {\n  font-size: inherit;\n  font-style: italic;\n  margin-bottom: 6px;\n}\n.wy-form-message p:last-child {\n  margin-bottom: 0;\n}\n\ninput {\n  line-height: normal;\n}\n\ninput[type=\"button\"], input[type=\"reset\"], input[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  *overflow: visible;\n}\ninput[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\"] {\n  -webkit-appearance: none;\n  padding: 6px;\n  display: inline-block;\n  border: 1px solid #ccc;\n  font-size: 80%;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  box-shadow: inset 0 1px 3px #ddd;\n  border-radius: 0;\n  -webkit-transition: border 0.3s linear;\n  -moz-transition: border 0.3s linear;\n  transition: border 0.3s linear;\n}\ninput[type=\"datetime-local\"] {\n  padding: 0.34375em 0.625em;\n}\ninput[disabled] {\n  cursor: default;\n}\ninput[type=\"checkbox\"], input[type=\"radio\"] {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  padding: 0;\n  margin-right: 0.3125em;\n  *height: 13px;\n  *width: 13px;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button, input[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\ninput[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 {\n  outline: 0;\n  outline: thin dotted \\9;\n  border-color: #333;\n}\ninput.no-focus:focus {\n  border-color: #ccc !important;\n}\ninput[type=\"file\"]:focus, input[type=\"radio\"]:focus, input[type=\"checkbox\"]:focus {\n  outline: thin dotted #333;\n  outline: 1px auto #129FEA;\n}\ninput[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] {\n  cursor: not-allowed;\n  background-color: #fafafa;\n}\n\ninput:focus:invalid, textarea:focus:invalid, select:focus:invalid {\n  color: #E74C3C;\n  border: 1px solid #E74C3C;\n}\n\ninput:focus:invalid:focus, textarea:focus:invalid:focus, select:focus:invalid:focus {\n  border-color: #E74C3C;\n}\n\ninput[type=\"file\"]:focus:invalid:focus, input[type=\"radio\"]:focus:invalid:focus, input[type=\"checkbox\"]:focus:invalid:focus {\n  outline-color: #E74C3C;\n}\n\ninput.wy-input-large {\n  padding: 12px;\n  font-size: 100%;\n}\n\ntextarea {\n  overflow: auto;\n  vertical-align: top;\n  width: 100%;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n}\n\nselect, textarea {\n  padding: 0.5em 0.625em;\n  display: inline-block;\n  border: 1px solid #ccc;\n  font-size: 80%;\n  box-shadow: inset 0 1px 3px #ddd;\n  -webkit-transition: border 0.3s linear;\n  -moz-transition: border 0.3s linear;\n  transition: border 0.3s linear;\n}\n\nselect {\n  border: 1px solid #ccc;\n  background-color: #fff;\n}\nselect[multiple] {\n  height: auto;\n}\n\nselect:focus, textarea:focus {\n  outline: 0;\n}\n\nselect[disabled], textarea[disabled], input[readonly], select[readonly], textarea[readonly] {\n  cursor: not-allowed;\n  background-color: #fafafa;\n}\n\ninput[type=\"radio\"][disabled], input[type=\"checkbox\"][disabled] {\n  cursor: not-allowed;\n}\n\n.wy-checkbox, .wy-radio {\n  margin: 6px 0;\n  color: #404040;\n  display: block;\n}\n.wy-checkbox input, .wy-radio input {\n  vertical-align: baseline;\n}\n\n.wy-form-message-inline {\n  display: inline-block;\n  *display: inline;\n  *zoom: 1;\n  vertical-align: middle;\n}\n\n.wy-input-prefix, .wy-input-suffix {\n  white-space: nowrap;\n  padding: 6px;\n}\n.wy-input-prefix .wy-input-context, .wy-input-suffix .wy-input-context {\n  line-height: 27px;\n  padding: 0 8px;\n  display: inline-block;\n  font-size: 80%;\n  background-color: #f3f6f6;\n  border: solid 1px #ccc;\n  color: #999;\n}\n\n.wy-input-suffix .wy-input-context {\n  border-left: 0;\n}\n\n.wy-input-prefix .wy-input-context {\n  border-right: 0;\n}\n\n.wy-switch {\n  width: 36px;\n  height: 12px;\n  margin: 12px 0;\n  position: relative;\n  border-radius: 4px;\n  background: #ccc;\n  cursor: pointer;\n  -webkit-transition: all 0.2s ease-in-out;\n  -moz-transition: all 0.2s ease-in-out;\n  transition: all 0.2s ease-in-out;\n}\n.wy-switch:before {\n  position: absolute;\n  content: \"\";\n  display: block;\n  width: 18px;\n  height: 18px;\n  border-radius: 4px;\n  background: #999;\n  left: -3px;\n  top: -3px;\n  -webkit-transition: all 0.2s ease-in-out;\n  -moz-transition: all 0.2s ease-in-out;\n  transition: all 0.2s ease-in-out;\n}\n.wy-switch:after {\n  content: \"false\";\n  position: absolute;\n  left: 48px;\n  display: block;\n  font-size: 12px;\n  color: #ccc;\n}\n\n.wy-switch.active {\n  background: #1e8449;\n}\n.wy-switch.active:before {\n  left: 24px;\n  background: #27AE60;\n}\n.wy-switch.active:after {\n  content: \"true\";\n}\n\n.wy-switch.disabled, .wy-switch.active.disabled {\n  cursor: not-allowed;\n}\n\n.wy-control-group.wy-control-group-error .wy-form-message, .wy-control-group.wy-control-group-error > label {\n  color: #E74C3C;\n}\n.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\"] {\n  border: solid 1px #E74C3C;\n}\n.wy-control-group.wy-control-group-error textarea {\n  border: solid 1px #E74C3C;\n}\n\n.wy-inline-validate {\n  white-space: nowrap;\n}\n.wy-inline-validate .wy-input-context {\n  padding: 0.5em 0.625em;\n  display: inline-block;\n  font-size: 80%;\n}\n\n.wy-inline-validate.wy-inline-validate-success .wy-input-context {\n  color: #27AE60;\n}\n\n.wy-inline-validate.wy-inline-validate-danger .wy-input-context {\n  color: #E74C3C;\n}\n\n.wy-inline-validate.wy-inline-validate-warning .wy-input-context {\n  color: #E67E22;\n}\n\n.wy-inline-validate.wy-inline-validate-info .wy-input-context {\n  color: #0E6FD2;\n}\n\n.rotate-90 {\n  -webkit-transform: rotate(90deg);\n  -moz-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  -o-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n\n.rotate-180 {\n  -webkit-transform: rotate(180deg);\n  -moz-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  -o-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n\n.rotate-270 {\n  -webkit-transform: rotate(270deg);\n  -moz-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  -o-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n\n.mirror {\n  -webkit-transform: scaleX(-1);\n  -moz-transform: scaleX(-1);\n  -ms-transform: scaleX(-1);\n  -o-transform: scaleX(-1);\n  transform: scaleX(-1);\n}\n.mirror.rotate-90 {\n  -webkit-transform: scaleX(-1) rotate(90deg);\n  -moz-transform: scaleX(-1) rotate(90deg);\n  -ms-transform: scaleX(-1) rotate(90deg);\n  -o-transform: scaleX(-1) rotate(90deg);\n  transform: scaleX(-1) rotate(90deg);\n}\n.mirror.rotate-180 {\n  -webkit-transform: scaleX(-1) rotate(180deg);\n  -moz-transform: scaleX(-1) rotate(180deg);\n  -ms-transform: scaleX(-1) rotate(180deg);\n  -o-transform: scaleX(-1) rotate(180deg);\n  transform: scaleX(-1) rotate(180deg);\n}\n.mirror.rotate-270 {\n  -webkit-transform: scaleX(-1) rotate(270deg);\n  -moz-transform: scaleX(-1) rotate(270deg);\n  -ms-transform: scaleX(-1) rotate(270deg);\n  -o-transform: scaleX(-1) rotate(270deg);\n  transform: scaleX(-1) rotate(270deg);\n}\n\n@media only screen and (max-width: 480px) {\n  .wy-form button[type=\"submit\"] {\n    margin: 0.7em 0 0;\n  }\n  .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\"] {\n    margin-bottom: 0.3em;\n    display: block;\n  }\n  .wy-form label {\n    margin-bottom: 0.3em;\n    display: block;\n  }\n\n  .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\"] {\n    margin-bottom: 0;\n  }\n\n  .wy-form-aligned .wy-control-group label {\n    margin-bottom: 0.3em;\n    text-align: left;\n    display: block;\n    width: 100%;\n  }\n  .wy-form-aligned .wy-control {\n    margin: 1.5em 0 0 0;\n  }\n\n  .wy-form .wy-help-inline, .wy-form-message-inline, .wy-form-message {\n    display: block;\n    font-size: 80%;\n    padding: 6px 0;\n  }\n}\n@media screen and (max-width: 768px) {\n  .tablet-hide {\n    display: none;\n  }\n}\n\n@media screen and (max-width: 480px) {\n  .mobile-hide {\n    display: none;\n  }\n}\n\n.float-left {\n  float: left;\n}\n\n.float-right {\n  float: right;\n}\n\n.full-width {\n  width: 100%;\n}\n\n.wy-table, .rst-content table.docutils, .rst-content table.field-list {\n  border-collapse: collapse;\n  border-spacing: 0;\n  empty-cells: show;\n  margin-bottom: 24px;\n}\n.wy-table caption, .rst-content table.docutils caption, .rst-content table.field-list caption {\n  color: #000;\n  font: italic 85%/1 arial, sans-serif;\n  padding: 1em 0;\n  text-align: center;\n}\n.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 {\n  font-size: 90%;\n  margin: 0;\n  overflow: visible;\n  padding: 8px 16px;\n}\n.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 {\n  border-left-width: 0;\n}\n.wy-table thead, .rst-content table.docutils thead, .rst-content table.field-list thead {\n  color: #000;\n  text-align: left;\n  vertical-align: bottom;\n  white-space: nowrap;\n}\n.wy-table thead th, .rst-content table.docutils thead th, .rst-content table.field-list thead th {\n  font-weight: bold;\n  border-bottom: solid 2px #e1e4e5;\n}\n.wy-table td, .rst-content table.docutils td, .rst-content table.field-list td {\n  background-color: transparent;\n  vertical-align: middle;\n}\n\n.wy-table td p, .rst-content table.docutils td p, .rst-content table.field-list td p {\n  line-height: 18px;\n}\n.wy-table td p:last-child, .rst-content table.docutils td p:last-child, .rst-content table.field-list td p:last-child {\n  margin-bottom: 0;\n}\n\n.wy-table .wy-table-cell-min, .rst-content table.docutils .wy-table-cell-min, .rst-content table.field-list .wy-table-cell-min {\n  width: 1%;\n  padding-right: 0;\n}\n.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] {\n  margin: 0;\n}\n\n.wy-table-secondary {\n  color: gray;\n  font-size: 90%;\n}\n\n.wy-table-tertiary {\n  color: gray;\n  font-size: 80%;\n}\n\n.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 {\n  background-color: #f3f6f6;\n}\n\n.wy-table-backed {\n  background-color: #f3f6f6;\n}\n\n/* BORDERED TABLES */\n.wy-table-bordered-all, .rst-content table.docutils {\n  border: 1px solid #e1e4e5;\n}\n.wy-table-bordered-all td, .rst-content table.docutils td {\n  border-bottom: 1px solid #e1e4e5;\n  border-left: 1px solid #e1e4e5;\n}\n.wy-table-bordered-all tbody > tr:last-child td, .rst-content table.docutils tbody > tr:last-child td {\n  border-bottom-width: 0;\n}\n\n.wy-table-bordered {\n  border: 1px solid #e1e4e5;\n}\n\n.wy-table-bordered-rows td {\n  border-bottom: 1px solid #e1e4e5;\n}\n.wy-table-bordered-rows tbody > tr:last-child td {\n  border-bottom-width: 0;\n}\n\n.wy-table-horizontal tbody > tr:last-child td {\n  border-bottom-width: 0;\n}\n.wy-table-horizontal td, .wy-table-horizontal th {\n  border-width: 0 0 1px 0;\n  border-bottom: 1px solid #e1e4e5;\n}\n.wy-table-horizontal tbody > tr:last-child td {\n  border-bottom-width: 0;\n}\n\n/* RESPONSIVE TABLES */\n.wy-table-responsive {\n  margin-bottom: 24px;\n  max-width: 100%;\n  overflow: auto;\n}\n.wy-table-responsive table {\n  margin-bottom: 0 !important;\n}\n.wy-table-responsive table td, .wy-table-responsive table th {\n  white-space: nowrap;\n}\n\na {\n  color: #0E6FD2;\n  text-decoration: none;\n  cursor: pointer;\n}\na:hover {\n  color: #107eef;\n}\na:visited {\n  color: #9B59B6;\n}\n\nhtml {\n  height: 100%;\n  overflow-x: hidden;\n}\n\nbody {\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  font-weight: normal;\n  color: #404040;\n  min-height: 100%;\n  overflow-x: hidden;\n  background: #edf0f2;\n}\n\n.wy-text-left {\n  text-align: left;\n}\n\n.wy-text-center {\n  text-align: center;\n}\n\n.wy-text-right {\n  text-align: right;\n}\n\n.wy-text-large {\n  font-size: 120%;\n}\n\n.wy-text-normal {\n  font-size: 100%;\n}\n\n.wy-text-small, small {\n  font-size: 80%;\n}\n\n.wy-text-strike {\n  text-decoration: line-through;\n}\n\n.wy-text-warning {\n  color: #E67E22 !important;\n}\n\na.wy-text-warning:hover {\n  color: #eb9950 !important;\n}\n\n.wy-text-info {\n  color: #0E6FD2 !important;\n}\n\na.wy-text-info:hover {\n  color: #2388f0 !important;\n}\n\n.wy-text-success {\n  color: #27AE60 !important;\n}\n\na.wy-text-success:hover {\n  color: #36d278 !important;\n}\n\n.wy-text-danger {\n  color: #E74C3C !important;\n}\n\na.wy-text-danger:hover {\n  color: #ed7669 !important;\n}\n\n.wy-text-neutral {\n  color: #404040 !important;\n}\n\na.wy-text-neutral:hover {\n  color: #595959 !important;\n}\n\nh1, h2, .rst-content .toctree-wrapper p.caption, h3, h4, h5, h6, legend {\n  margin-top: 0;\n  font-weight: 700;\n  font-family: \"Roboto Slab\", \"ff-tisa-web-pro\", \"Georgia\", Arial, sans-serif;\n}\n\np {\n  line-height: 24px;\n  margin: 0;\n  font-size: 16px;\n  margin-bottom: 24px;\n}\n\nh1 {\n  font-size: 175%;\n}\n\nh2, .rst-content .toctree-wrapper p.caption {\n  font-size: 150%;\n}\n\nh3 {\n  font-size: 125%;\n}\n\nh4 {\n  font-size: 115%;\n}\n\nh5 {\n  font-size: 110%;\n}\n\nh6 {\n  font-size: 100%;\n}\n\nhr {\n  display: block;\n  height: 1px;\n  border: 0;\n  border-top: 1px solid #e1e4e5;\n  margin: 24px 0;\n  padding: 0;\n}\n\ncode, .rst-content tt, .rst-content code {\n  white-space: nowrap;\n  max-width: 100%;\n  background: #fff;\n  border: solid 1px #e1e4e5;\n  font-size: 75%;\n  padding: 0 5px;\n  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;\n  color: #E74C3C;\n  overflow-x: auto;\n}\ncode.code-large, .rst-content tt.code-large {\n  font-size: 90%;\n}\n\n.wy-plain-list-disc, .rst-content .section ul, .rst-content .toctree-wrapper ul, article ul {\n  list-style: disc;\n  line-height: 24px;\n  margin-bottom: 24px;\n}\n.wy-plain-list-disc li, .rst-content .section ul li, .rst-content .toctree-wrapper ul li, article ul li {\n  list-style: disc;\n  margin-left: 24px;\n}\n.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 {\n  margin-bottom: 0;\n}\n.wy-plain-list-disc li ul, .rst-content .section ul li ul, .rst-content .toctree-wrapper ul li ul, article ul li ul {\n  margin-bottom: 0;\n}\n.wy-plain-list-disc li li, .rst-content .section ul li li, .rst-content .toctree-wrapper ul li li, article ul li li {\n  list-style: circle;\n}\n.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 {\n  list-style: square;\n}\n.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 {\n  list-style: decimal;\n}\n\n.wy-plain-list-decimal, .rst-content .section ol, .rst-content ol.arabic, article ol {\n  list-style: decimal;\n  line-height: 24px;\n  margin-bottom: 24px;\n}\n.wy-plain-list-decimal li, .rst-content .section ol li, .rst-content ol.arabic li, article ol li {\n  list-style: decimal;\n  margin-left: 24px;\n}\n.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 {\n  margin-bottom: 0;\n}\n.wy-plain-list-decimal li ul, .rst-content .section ol li ul, .rst-content ol.arabic li ul, article ol li ul {\n  margin-bottom: 0;\n}\n.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 {\n  list-style: disc;\n}\n\n.codeblock-example {\n  border: 1px solid #e1e4e5;\n  border-bottom: none;\n  padding: 24px;\n  padding-top: 48px;\n  font-weight: 500;\n  background: #fff;\n  position: relative;\n}\n.codeblock-example:after {\n  content: \"Example\";\n  position: absolute;\n  top: 0px;\n  left: 0px;\n  background: #9B59B6;\n  color: white;\n  padding: 6px 12px;\n}\n.codeblock-example.prettyprint-example-only {\n  border: 1px solid #e1e4e5;\n  margin-bottom: 24px;\n}\n\n.codeblock, pre.literal-block, .rst-content .literal-block, .rst-content pre.literal-block, div[class^='highlight'] {\n  border: 1px solid #e1e4e5;\n  padding: 0px;\n  overflow-x: auto;\n  background: #fff;\n  margin: 1px 0 24px 0;\n}\n.codeblock div[class^='highlight'], pre.literal-block div[class^='highlight'], .rst-content .literal-block div[class^='highlight'], div[class^='highlight'] div[class^='highlight'] {\n  border: none;\n  background: none;\n  margin: 0;\n}\n\ndiv[class^='highlight'] td.code {\n  width: 100%;\n}\n\n.linenodiv pre {\n  border-right: solid 1px #e6e9ea;\n  margin: 0;\n  padding: 12px 12px;\n  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;\n  font-size: 12px;\n  line-height: 1.5;\n  color: #d9d9d9;\n}\n\ndiv[class^='highlight'] pre {\n  white-space: pre;\n  margin: 0;\n  padding: 12px 12px;\n  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;\n  font-size: 12px;\n  line-height: 1.5;\n  display: block;\n  overflow: auto;\n  color: #404040;\n}\n\n@media print {\n  .codeblock, pre.literal-block, .rst-content .literal-block, .rst-content pre.literal-block, div[class^='highlight'], div[class^='highlight'] pre {\n    white-space: pre-wrap;\n  }\n}\n.hll {\n  background-color: #ffffcc;\n  margin: 0 -12px;\n  padding: 0 12px;\n  display: block;\n}\n\n.c {\n  color: #999988;\n  font-style: italic;\n}\n\n.err {\n  color: #a61717;\n  background-color: #e3d2d2;\n}\n\n.k {\n  font-weight: bold;\n}\n\n.o {\n  font-weight: bold;\n}\n\n.cm {\n  color: #999988;\n  font-style: italic;\n}\n\n.cp {\n  color: #999999;\n  font-weight: bold;\n}\n\n.c1 {\n  color: #999988;\n  font-style: italic;\n}\n\n.cs {\n  color: #999999;\n  font-weight: bold;\n  font-style: italic;\n}\n\n.gd {\n  color: #000000;\n  background-color: #ffdddd;\n}\n\n.gd .x {\n  color: #000000;\n  background-color: #ffaaaa;\n}\n\n.ge {\n  font-style: italic;\n}\n\n.gr {\n  color: #aa0000;\n}\n\n.gh {\n  color: #999999;\n}\n\n.gi {\n  color: #000000;\n  background-color: #ddffdd;\n}\n\n.gi .x {\n  color: #000000;\n  background-color: #aaffaa;\n}\n\n.go {\n  color: #888888;\n}\n\n.gp {\n  color: #555555;\n}\n\n.gs {\n  font-weight: bold;\n}\n\n.gu {\n  color: #800080;\n  font-weight: bold;\n}\n\n.gt {\n  color: #aa0000;\n}\n\n.kc {\n  font-weight: bold;\n}\n\n.kd {\n  font-weight: bold;\n}\n\n.kn {\n  font-weight: bold;\n}\n\n.kp {\n  font-weight: bold;\n}\n\n.kr {\n  font-weight: bold;\n}\n\n.kt {\n  color: #445588;\n  font-weight: bold;\n}\n\n.m {\n  color: #009999;\n}\n\n.s {\n  color: #dd1144;\n}\n\n.n {\n  color: #333333;\n}\n\n.na {\n  color: teal;\n}\n\n.nb {\n  color: #0086b3;\n}\n\n.nc {\n  color: #445588;\n  font-weight: bold;\n}\n\n.no {\n  color: teal;\n}\n\n.ni {\n  color: purple;\n}\n\n.ne {\n  color: #990000;\n  font-weight: bold;\n}\n\n.nf {\n  color: #990000;\n  font-weight: bold;\n}\n\n.nn {\n  color: #555555;\n}\n\n.nt {\n  color: navy;\n}\n\n.nv {\n  color: teal;\n}\n\n.ow {\n  font-weight: bold;\n}\n\n.w {\n  color: #bbbbbb;\n}\n\n.mf {\n  color: #009999;\n}\n\n.mh {\n  color: #009999;\n}\n\n.mi {\n  color: #009999;\n}\n\n.mo {\n  color: #009999;\n}\n\n.sb {\n  color: #dd1144;\n}\n\n.sc {\n  color: #dd1144;\n}\n\n.sd {\n  color: #dd1144;\n}\n\n.s2 {\n  color: #dd1144;\n}\n\n.se {\n  color: #dd1144;\n}\n\n.sh {\n  color: #dd1144;\n}\n\n.si {\n  color: #dd1144;\n}\n\n.sx {\n  color: #dd1144;\n}\n\n.sr {\n  color: #009926;\n}\n\n.s1 {\n  color: #dd1144;\n}\n\n.ss {\n  color: #990073;\n}\n\n.bp {\n  color: #999999;\n}\n\n.vc {\n  color: teal;\n}\n\n.vg {\n  color: teal;\n}\n\n.vi {\n  color: teal;\n}\n\n.il {\n  color: #009999;\n}\n\n.gc {\n  color: #999;\n  background-color: #EAF2F5;\n}\n\n.wy-breadcrumbs li {\n  display: inline-block;\n}\n.wy-breadcrumbs li.wy-breadcrumbs-aside {\n  float: right;\n}\n.wy-breadcrumbs li a {\n  display: inline-block;\n  padding: 5px;\n}\n.wy-breadcrumbs li a:first-child {\n  padding-left: 0;\n}\n.wy-breadcrumbs li code, .wy-breadcrumbs li .rst-content tt, .rst-content .wy-breadcrumbs li tt {\n  padding: 5px;\n  border: none;\n  background: none;\n}\n.wy-breadcrumbs li code.literal, .wy-breadcrumbs li .rst-content tt.literal, .rst-content .wy-breadcrumbs li tt.literal {\n  color: #404040;\n}\n\n.wy-breadcrumbs-extra {\n  margin-bottom: 0;\n  color: #b3b3b3;\n  font-size: 80%;\n  display: inline-block;\n}\n\n@media screen and (max-width: 480px) {\n  .wy-breadcrumbs-extra {\n    display: none;\n  }\n\n  .wy-breadcrumbs li.wy-breadcrumbs-aside {\n    display: none;\n  }\n}\n@media print {\n  .wy-breadcrumbs li.wy-breadcrumbs-aside {\n    display: none;\n  }\n}\nem {\n  font-style: normal;\n}\n\na:visited {\n  color: #0E6FD2;\n}\n\n.simple {\n  margin-bottom: 0 !important;\n}\n\na.btn.btn-neutral {\n  padding: 5px 14px;\n  background-color: #ffffff !important;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  margin-top: 15px;\n  box-shadow: none;\n  color: #0E6FD2 !important;\n}\n\na.btn.btn-neutral:hover {\n  background-color: #eee !important;\n}\n\n.wy-side-scroll .wy-side-nav-search input[type=text] {\n  border-radius: 0 !important;\n  border: 1px solid #00b7ee;\n}\n\n.wy-affixs {\n  position: fixed;\n  top: 1.618em;\n}\n\n.wy-menu a:hover {\n  text-decoration: none;\n}\n\n.wy-menu-horiz {\n  *zoom: 1;\n}\n.wy-menu-horiz:before, .wy-menu-horiz:after {\n  display: table;\n  content: \"\";\n}\n.wy-menu-horiz:after {\n  clear: both;\n}\n.wy-menu-horiz ul, .wy-menu-horiz li {\n  display: inline-block;\n}\n.wy-menu-horiz li:hover {\n  background: rgba(255, 255, 255, 0.1);\n}\n.wy-menu-horiz li.divide-left {\n  border-left: solid 1px #404040;\n}\n.wy-menu-horiz li.divide-right {\n  border-right: solid 1px #404040;\n}\n.wy-menu-horiz a {\n  height: 32px;\n  display: inline-block;\n  line-height: 32px;\n  padding: 0 16px;\n}\n\n.wy-menu-vertical {\n  width: 300px;\n}\n.wy-menu-vertical header, .wy-menu-vertical p.caption {\n  height: 32px;\n  display: inline-block;\n  line-height: 32px;\n  padding: 0 1.618em;\n  margin-bottom: 0;\n  display: block;\n  font-weight: bold;\n  text-transform: uppercase;\n  font-size: 80%;\n  color: #555;\n  white-space: nowrap;\n}\n.wy-menu-vertical ul {\n  margin-bottom: 0;\n}\n.wy-menu-vertical li.divide-top {\n  border-top: solid 1px #404040;\n}\n.wy-menu-vertical li.divide-bottom {\n  border-bottom: solid 1px #404040;\n}\n.wy-menu-vertical li.current {\n  background: #e3e3e3;\n}\n.wy-menu-vertical li.current a {\n  color: gray;\n  border-right: solid 1px #c9c9c9;\n  padding: 0.4045em 2.427em;\n}\n.wy-menu-vertical li.current a:hover {\n  background: #d6d6d6;\n}\n.wy-menu-vertical li code, .wy-menu-vertical li .rst-content tt, .rst-content .wy-menu-vertical li tt {\n  border: none;\n  background: inherit;\n  color: inherit;\n  padding-left: 0;\n  padding-right: 0;\n}\n.wy-menu-vertical li span.toctree-expand {\n  display: block;\n  float: left;\n  margin-left: -1.2em;\n  font-size: 0.8em;\n  line-height: 1.6em;\n  color: #4d4d4d;\n}\n.wy-menu-vertical li.on a, .wy-menu-vertical li.current > a {\n  color: #0E6FD2;\n  padding: 0.4045em 1.618em;\n  font-weight: bold;\n  position: relative;\n  background: #343131 !important;\n  border: none;\n  padding-left: 1.618em -4px;\n}\n.wy-menu-vertical li.on a:hover, .wy-menu-vertical li.current > a:hover {\n  background: #fcfcfc;\n}\n.wy-menu-vertical li.on a:hover span.toctree-expand, .wy-menu-vertical li.current > a:hover span.toctree-expand {\n  color: gray;\n}\n.wy-menu-vertical li.on a span.toctree-expand, .wy-menu-vertical li.current > a span.toctree-expand {\n  display: block;\n  font-size: 0.8em;\n  line-height: 1.6em;\n  color: #333333;\n}\n.wy-menu-vertical li.toctree-l1.current, .wy-menu-vertical li.toctree-l1.current li.toctree-l2, .wy-menu-vertical li.toctree-l2.current li {\n  color: #0E6FD2;\n  background: #343131;\n}\n.wy-menu-vertical li.toctree-l1.current span.toctree-expand, .wy-menu-vertical li.toctree-l1.current li.toctree-l2 span.toctree-expand, .wy-menu-vertical li.toctree-l2.current li span.toctree-expand {\n  color: #343131;\n}\n.wy-menu-vertical li.toctree-l1.current > a:hover, .wy-menu-vertical li.toctree-l1.current li.toctree-l2 > a:hover, .wy-menu-vertical li.toctree-l2.current li > a:hover {\n  color: #0E6FD2;\n  background: #343131;\n  border-bottom: 0;\n  border-top: 0;\n}\n.wy-menu-vertical li.toctree-l1.current > a:hover span.toctree-expand, .wy-menu-vertical li.toctree-l1.current li.toctree-l2 > a:hover span.toctree-expand, .wy-menu-vertical li.toctree-l2.current li > a:hover span.toctree-expand {\n  color: #0E6FD2;\n}\n.wy-menu-vertical li.toctree-l1.current > ul, .wy-menu-vertical li.toctree-l1.current li.toctree-l2 > ul, .wy-menu-vertical li.toctree-l2.current li > ul {\n  display: none;\n}\n.wy-menu-vertical li.toctree-l1.current.current > ul, .wy-menu-vertical li.toctree-l1.current li.toctree-l2.current > ul, .wy-menu-vertical li.toctree-l2.current li.current > ul {\n  display: block;\n}\n.wy-menu-vertical li.toctree-l2 a {\n  border-right: 0;\n}\n.wy-menu-vertical li.toctree-l2.current {\n  background: #343131;\n}\n.wy-menu-vertical li.toctree-l2.current > a {\n  background: #343131;\n  padding: 0.4045em 2.427em;\n}\n.wy-menu-vertical li.toctree-l2.current > a span.toctree-expand {\n  color: #343131;\n}\n.wy-menu-vertical li.toctree-l2.current li.toctree-l3 > a {\n  display: block;\n  background: #343131;\n  padding: 0.4045em 4.045em;\n}\n.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand {\n  color: gray;\n  background: #343131;\n}\n.wy-menu-vertical li.toctree-l2 span.toctree-expand {\n  color: #a3a3a3;\n}\n.wy-menu-vertical li.toctree-l3 {\n  font-size: 0.9em;\n}\n.wy-menu-vertical li.toctree-l3 a {\n  border-right: 0;\n}\n.wy-menu-vertical li.toctree-l3.current > a {\n  background: #343131;\n  padding: 0.4045em 4.045em;\n}\n.wy-menu-vertical li.toctree-l3.current li.toctree-l4 > a {\n  display: block;\n  background: #343131;\n  padding: 0.4045em 5.663em;\n  border-top: none;\n  border-bottom: none;\n}\n.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand {\n  color: #0E6FD2;\n}\n.wy-menu-vertical li.toctree-l3 span.toctree-expand {\n  color: #969696;\n}\n.wy-menu-vertical li.toctree-l4 {\n  font-size: 0.9em;\n}\n.wy-menu-vertical li.current ul {\n  display: block;\n}\n.wy-menu-vertical li ul {\n  margin-bottom: 0;\n  display: none;\n}\n.wy-menu-vertical .local-toc li ul {\n  display: block;\n}\n.wy-menu-vertical li ul li a {\n  margin-bottom: 0;\n  color: #b3b3b3;\n  font-weight: normal;\n}\n.wy-menu-vertical a {\n  display: inline-block;\n  line-height: 18px;\n  padding: 0.4045em 1.618em;\n  display: block;\n  position: relative;\n  font-size: 90%;\n  color: #b3b3b3;\n}\n.wy-menu-vertical a:hover {\n  background-color: #4e4a4a;\n  cursor: pointer;\n}\n.wy-menu-vertical a:hover span.toctree-expand {\n  color: #b3b3b3;\n}\n.wy-menu-vertical a:active {\n  background-color: #0E6FD2;\n  cursor: pointer;\n  color: #fff;\n}\n.wy-menu-vertical a:active span.toctree-expand {\n  color: #fff;\n}\n\n.wy-side-nav-search {\n  display: block;\n  width: 300px;\n  padding: 0.809em;\n  margin-bottom: 0.809em;\n  z-index: 200;\n  background-image: linear-gradient(#0E7EE4 0%, #343131 100%);\n  background-color: #0E6FD2;\n  text-align: center;\n  color: #fcfcfc;\n}\n.wy-side-nav-search input[type=text] {\n  width: 100%;\n  border-radius: 50px;\n  padding: 6px 12px;\n  border-color: #0c62ba;\n}\n.wy-side-nav-search img {\n  display: block;\n  margin: auto auto 0.809em auto;\n  height: 45px;\n  width: 45px;\n  background-color: #0E6FD2;\n  padding: 5px;\n  border-radius: 100%;\n}\n.wy-side-nav-search > a, .wy-side-nav-search .wy-dropdown > a {\n  color: #fcfcfc;\n  font-size: 100%;\n  font-weight: bold;\n  display: inline-block;\n  padding: 4px 6px;\n  margin-bottom: 0.809em;\n}\n.wy-side-nav-search > a:hover, .wy-side-nav-search .wy-dropdown > a:hover {\n  background: rgba(255, 255, 255, 0.1);\n}\n.wy-side-nav-search > a img.logo, .wy-side-nav-search .wy-dropdown > a img.logo {\n  display: block;\n  margin: 0 auto;\n  height: auto;\n  width: auto;\n  border-radius: 0;\n  max-width: 100%;\n  background: transparent;\n}\n.wy-side-nav-search > a.icon img.logo, .wy-side-nav-search .wy-dropdown > a.icon img.logo {\n  margin-top: 0.85em;\n}\n.wy-side-nav-search > div.version {\n  margin-top: -0.4045em;\n  margin-bottom: 0.809em;\n  font-weight: normal;\n  color: rgba(255, 255, 255, 0.3);\n}\n\n.wy-nav .wy-menu-vertical header {\n  color: #0E6FD2;\n}\n.wy-nav .wy-menu-vertical a {\n  color: #b3b3b3;\n}\n.wy-nav .wy-menu-vertical a:hover {\n  background-color: #0E6FD2;\n  color: #fff;\n}\n\n[data-menu-wrap] {\n  -webkit-transition: all 0.2s ease-in;\n  -moz-transition: all 0.2s ease-in;\n  transition: all 0.2s ease-in;\n  position: absolute;\n  opacity: 1;\n  width: 100%;\n  opacity: 0;\n}\n[data-menu-wrap].move-center {\n  left: 0;\n  right: auto;\n  opacity: 1;\n}\n[data-menu-wrap].move-left {\n  right: auto;\n  left: -100%;\n  opacity: 0;\n}\n[data-menu-wrap].move-right {\n  right: -100%;\n  left: auto;\n  opacity: 0;\n}\n\n.wy-body-for-nav {\n  background: left repeat-y #fcfcfc;\n  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);\n  background-size: 300px 1px;\n  color: #444;\n}\n\n.wy-grid-for-nav {\n  position: absolute;\n  width: 100%;\n  height: 100%;\n}\n\n.wy-nav-side {\n  position: fixed;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  padding-bottom: 2em;\n  width: 300px;\n  overflow-x: hidden;\n  overflow-y: hidden;\n  min-height: 100%;\n  background: #343131;\n  z-index: 200;\n}\n\n.wy-side-scroll {\n  width: 320px;\n  position: relative;\n  overflow-x: hidden;\n  overflow-y: scroll;\n  height: 100%;\n}\n\n.wy-nav-top {\n  display: none;\n  background: #0E6FD2;\n  color: #fff;\n  padding: 0.4045em 0.809em;\n  position: relative;\n  line-height: 50px;\n  text-align: center;\n  font-size: 100%;\n  *zoom: 1;\n}\n.wy-nav-top:before, .wy-nav-top:after {\n  display: table;\n  content: \"\";\n}\n.wy-nav-top:after {\n  clear: both;\n}\n.wy-nav-top a {\n  color: #fff;\n  font-weight: bold;\n}\n.wy-nav-top img {\n  margin-right: 12px;\n  height: 45px;\n  width: 45px;\n  background-color: #0E6FD2;\n  padding: 5px;\n  border-radius: 100%;\n}\n.wy-nav-top i {\n  font-size: 30px;\n  float: left;\n  cursor: pointer;\n  padding-top: inherit;\n}\n\n.wy-nav-content-wrap {\n  margin-left: 300px;\n  background: #fcfcfc;\n  min-height: 100%;\n}\n\n.wy-nav-content {\n  padding: 1.618em 3.236em;\n  height: 100%;\n  min-height: 100vh;\n  margin: auto;\n}\n\n.wy-body-mask {\n  position: fixed;\n  width: 100%;\n  height: 100%;\n  background: rgba(0, 0, 0, 0.2);\n  display: none;\n  z-index: 499;\n}\n.wy-body-mask.on {\n  display: block;\n}\n\nfooter {\n  color: #999;\n}\nfooter p {\n  margin-bottom: 12px;\n}\nfooter span.commit code, footer span.commit .rst-content tt, .rst-content footer span.commit tt {\n  padding: 0px;\n  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;\n  font-size: 1em;\n  background: none;\n  border: none;\n  color: #999;\n}\n\n.rst-footer-buttons {\n  *zoom: 1;\n}\n.rst-footer-buttons:before, .rst-footer-buttons:after {\n  display: table;\n  content: \"\";\n}\n.rst-footer-buttons:after {\n  clear: both;\n}\n\n.document {\n  min-height: 58vh;\n}\n\n#search-results .search li {\n  margin-bottom: 24px;\n  border-bottom: solid 1px #e1e4e5;\n  padding-bottom: 24px;\n}\n#search-results .search li:first-child {\n  border-top: solid 1px #e1e4e5;\n  padding-top: 24px;\n}\n#search-results .search li a {\n  font-size: 120%;\n  margin-bottom: 12px;\n  display: inline-block;\n}\n#search-results .context {\n  color: gray;\n  font-size: 90%;\n}\n\n@media screen and (max-width: 768px) {\n  .wy-body-for-nav {\n    background: #fcfcfc;\n  }\n\n  .wy-nav-top {\n    display: block;\n  }\n\n  .wy-nav-side {\n    left: -300px;\n  }\n  .wy-nav-side.shift {\n    width: 85%;\n    left: 0;\n  }\n\n  .wy-side-scroll {\n    width: auto;\n  }\n\n  .wy-side-nav-search {\n    width: auto;\n  }\n\n  .wy-menu.wy-menu-vertical {\n    width: auto;\n  }\n\n  .wy-nav-content-wrap {\n    margin-left: 0;\n  }\n  .wy-nav-content-wrap .wy-nav-content {\n    padding: 1.618em;\n  }\n  .wy-nav-content-wrap.shift {\n    position: fixed;\n    min-width: 100%;\n    left: 85%;\n    top: 0;\n    height: 100%;\n    overflow: hidden;\n  }\n}\n@media screen and (min-width: 1400px) {\n  .wy-nav-content-wrap {\n    background: rgba(0, 0, 0, 0.05);\n  }\n\n  .wy-nav-content {\n    margin: 0;\n    background: #fcfcfc;\n  }\n\n  .document {\n    min-height: 71vh;\n  }\n}\n@media print {\n  .rst-versions, footer, .wy-nav-side {\n    display: none;\n  }\n\n  .wy-nav-content-wrap {\n    margin-left: 0;\n  }\n}\n.rst-versions {\n  position: fixed;\n  bottom: 0;\n  left: 0;\n  width: 300px;\n  color: #fcfcfc;\n  background: #1f1d1d;\n  border-top: solid 10px #343131;\n  font-family: \"Lato\", \"proxima-nova\", \"Helvetica Neue\", Arial, sans-serif;\n  z-index: 400;\n}\n.rst-versions a {\n  color: #0E6FD2;\n  text-decoration: none;\n}\n.rst-versions .rst-badge-small {\n  display: none;\n}\n.rst-versions .rst-current-version {\n  padding: 12px;\n  background-color: #272525;\n  display: block;\n  text-align: right;\n  font-size: 90%;\n  cursor: pointer;\n  color: #27AE60;\n  *zoom: 1;\n}\n.rst-versions .rst-current-version:before, .rst-versions .rst-current-version:after {\n  display: table;\n  content: \"\";\n}\n.rst-versions .rst-current-version:after {\n  clear: both;\n}\n.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 {\n  color: #fcfcfc;\n}\n.rst-versions .rst-current-version .fa-book, .rst-versions .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions .rst-current-version.rst-out-of-date {\n  background-color: #E74C3C;\n  color: #fff;\n}\n.rst-versions .rst-current-version.rst-active-old-version {\n  background-color: #F1C40F;\n  color: #000;\n}\n.rst-versions.shift-up .rst-other-versions {\n  display: block;\n}\n.rst-versions .rst-other-versions {\n  font-size: 90%;\n  padding: 12px;\n  color: gray;\n  display: none;\n}\n.rst-versions .rst-other-versions hr {\n  display: block;\n  height: 1px;\n  border: 0;\n  margin: 20px 0;\n  padding: 0;\n  border-top: solid 1px #413d3d;\n}\n.rst-versions .rst-other-versions dd {\n  display: inline-block;\n  margin: 0;\n}\n.rst-versions .rst-other-versions dd a {\n  display: inline-block;\n  padding: 6px;\n  color: #fcfcfc;\n}\n.rst-versions.rst-badge {\n  width: auto;\n  bottom: 20px;\n  right: 20px;\n  left: auto;\n  border: none;\n  max-width: 300px;\n}\n.rst-versions.rst-badge .icon-book {\n  float: none;\n}\n.rst-versions.rst-badge .fa-book, .rst-versions.rst-badge .icon-book {\n  float: none;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version {\n  text-align: right;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version .fa-book, .rst-versions.rst-badge.shift-up .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions.rst-badge.shift-up .rst-current-version .icon-book {\n  float: left;\n}\n.rst-versions.rst-badge .rst-current-version {\n  width: auto;\n  height: 30px;\n  line-height: 30px;\n  padding: 0 6px;\n  display: block;\n  text-align: center;\n}\n\n@media screen and (max-width: 768px) {\n  .rst-versions {\n    width: 85%;\n    display: none;\n  }\n  .rst-versions.shift {\n    display: block;\n  }\n\n  img {\n    width: 100%;\n    height: auto;\n  }\n}\n.rst-content img {\n  max-width: 100%;\n  height: auto !important;\n}\n.rst-content div.figure {\n  margin-bottom: 24px;\n}\n.rst-content div.figure p.caption {\n  font-style: italic;\n}\n.rst-content div.figure.align-center {\n  text-align: center;\n}\n.rst-content .section > img, .rst-content .section > a > img {\n  margin-bottom: 24px;\n}\n.rst-content blockquote {\n  margin-left: 24px;\n  line-height: 24px;\n  margin-bottom: 24px;\n}\n.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 {\n  margin-bottom: 0;\n}\n.rst-content .admonition-title:before {\n  margin-right: 4px;\n}\n.rst-content .admonition table {\n  border-color: rgba(0, 0, 0, 0.1);\n}\n.rst-content .admonition table td, .rst-content .admonition table th {\n  background: transparent !important;\n  border-color: rgba(0, 0, 0, 0.1) !important;\n}\n.rst-content .toctree-wrapper ul li {\n  list-style: none;\n  margin-left: 20px;\n}\n.rst-content .section ol.loweralpha, .rst-content .section ol.loweralpha li {\n  list-style: lower-alpha;\n}\n.rst-content .section ol.upperalpha, .rst-content .section ol.upperalpha li {\n  list-style: upper-alpha;\n}\n.rst-content .section ol p, .rst-content .section ul p {\n  margin-bottom: 12px;\n}\n.rst-content .line-block {\n  margin-left: 24px;\n}\n.rst-content .topic .topic-title {\n  font-size: 16px;\n  line-height: 20px;\n  color: #555;\n  font-weight: bold;\n  margin: 12px 0;\n}\n.rst-content .topic {\n  margin: 0 30px;\n}\n.rst-content .toc-backref {\n  color: #404040;\n}\n.rst-content .align-right {\n  float: right;\n  margin: 0 0 24px 24px;\n}\n.rst-content .align-left {\n  float: left;\n  margin: 0 24px 24px 0;\n}\n.rst-content .align-center {\n  margin: auto;\n  display: block;\n}\n.rst-content .document h1 {\n  font-size: 23px;\n  line-height: 40px;\n}\n.rst-content .document h2, .rst-content .document .toctree-wrapper p.caption, .rst-content .toctree-wrapper .document p.caption {\n  font-size: 21px;\n  line-height: 30px;\n  font-weight: 400;\n  margin-top: 20px;\n}\n.rst-content .document h3 {\n  font-size: 18px;\n  line-height: 20px;\n  font-weight: 400;\n  margin-top: 15px;\n}\n.rst-content .document p {\n  font-size: 14px;\n  margin: 0 0 1px 0;\n}\n.rst-content .document a.reference.external, .rst-content .document a.reference.external em, .rst-content .document a.reference.internal, .rst-content .document a.reference.internal em {\n  color: #0E6FD2;\n  text-decoration: none;\n  cursor: pointer;\n  font-style: normal;\n}\n.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 {\n  display: none;\n  visibility: hidden;\n  font-size: 14px;\n}\n.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 {\n  visibility: visible;\n  content: \"\";\n  font-family: FontAwesome;\n  display: inline-block;\n}\n.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 {\n  display: inline-block;\n}\n.rst-content .sidebar {\n  float: right;\n  width: 40%;\n  display: block;\n  margin: 0 0 24px 24px;\n  padding: 24px;\n  background: #f3f6f6;\n  border: solid 1px #e1e4e5;\n}\n.rst-content .sidebar p, .rst-content .sidebar ul, .rst-content .sidebar dl {\n  font-size: 90%;\n}\n.rst-content .sidebar .last {\n  margin-bottom: 0;\n}\n.rst-content .sidebar .sidebar-title {\n  display: block;\n  font-family: \"Roboto Slab\", \"ff-tisa-web-pro\", \"Georgia\", Arial, sans-serif;\n  font-weight: bold;\n  background: #e1e4e5;\n  padding: 6px 12px;\n  margin: -24px;\n  margin-bottom: 24px;\n  font-size: 100%;\n}\n.rst-content .highlighted {\n  background: #F1C40F;\n  display: inline-block;\n  font-weight: bold;\n  padding: 0 6px;\n}\n.rst-content .footnote-reference, .rst-content .citation-reference {\n  vertical-align: super;\n  font-size: 90%;\n}\n.rst-content table.docutils.citation, .rst-content table.docutils.footnote {\n  background: none;\n  border: none;\n  color: #999;\n}\n.rst-content table.docutils.citation td, .rst-content table.docutils.citation tr, .rst-content table.docutils.footnote td, .rst-content table.docutils.footnote tr {\n  border: none;\n  background-color: transparent !important;\n  white-space: normal;\n}\n.rst-content table.docutils.citation td.label, .rst-content table.docutils.footnote td.label {\n  padding-left: 0;\n  padding-right: 0;\n  vertical-align: top;\n}\n.rst-content table.docutils.citation tt, .rst-content table.docutils.citation code, .rst-content table.docutils.footnote tt, .rst-content table.docutils.footnote code {\n  color: #555;\n}\n.rst-content table.field-list {\n  border: none;\n}\n.rst-content table.field-list td {\n  border: none;\n  padding-top: 5px;\n}\n.rst-content table.field-list td > strong {\n  display: inline-block;\n  margin-top: 3px;\n}\n.rst-content table.field-list .field-name {\n  padding-right: 10px;\n  text-align: left;\n  white-space: nowrap;\n}\n.rst-content table.field-list .field-body {\n  text-align: left;\n  padding-left: 0;\n}\n.rst-content tt, .rst-content tt, .rst-content code {\n  color: #000;\n  padding: 2px 5px;\n}\n.rst-content tt big, .rst-content tt em, .rst-content tt big, .rst-content code big, .rst-content tt em, .rst-content code em {\n  font-size: 100% !important;\n  line-height: normal;\n}\n.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal {\n  color: #888;\n  background-color: rgba(0, 0, 0, 0.04);\n  border: none;\n  font-size: 13px;\n}\n.rst-content tt.xref, a .rst-content tt, .rst-content tt.xref, .rst-content code.xref, a .rst-content tt, a .rst-content code {\n  font-weight: bold;\n  color: #404040;\n}\n.rst-content a tt, .rst-content a tt, .rst-content a code {\n  color: #0E6FD2;\n}\n.rst-content dl {\n  margin-bottom: 24px;\n}\n.rst-content dl dt {\n  font-weight: bold;\n}\n.rst-content dl p, .rst-content dl table, .rst-content dl ul, .rst-content dl ol {\n  margin-bottom: 12px !important;\n}\n.rst-content dl dd {\n  margin: 0 0 12px 24px;\n}\n.rst-content dl:not(.docutils) {\n  margin-bottom: 24px;\n}\n.rst-content dl:not(.docutils) dt {\n  display: inline-block;\n  margin: 6px 0;\n  font-size: 90%;\n  line-height: normal;\n  background: #e2effd;\n  color: #0E6FD2;\n  border-top: solid 3px #53a2f4;\n  padding: 6px;\n  position: relative;\n}\n.rst-content dl:not(.docutils) dt:before {\n  color: #53a2f4;\n}\n.rst-content dl:not(.docutils) dt .headerlink {\n  color: #404040;\n  font-size: 100% !important;\n}\n.rst-content dl:not(.docutils) dl dt {\n  margin-bottom: 6px;\n  border: none;\n  border-left: solid 3px #cccccc;\n  background: #f0f0f0;\n  color: #555;\n}\n.rst-content dl:not(.docutils) dl dt .headerlink {\n  color: #404040;\n  font-size: 100% !important;\n}\n.rst-content dl:not(.docutils) dt:first-child {\n  margin-top: 0;\n}\n.rst-content dl:not(.docutils) tt, .rst-content dl:not(.docutils) tt, .rst-content dl:not(.docutils) code {\n  font-weight: bold;\n}\n.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 {\n  background-color: transparent;\n  border: none;\n  padding: 0;\n  font-size: 100% !important;\n}\n.rst-content dl:not(.docutils) tt.descname, .rst-content dl:not(.docutils) tt.descname, .rst-content dl:not(.docutils) code.descname {\n  font-weight: bold;\n}\n.rst-content dl:not(.docutils) .optional {\n  display: inline-block;\n  padding: 0 4px;\n  color: #000;\n  font-weight: bold;\n}\n.rst-content dl:not(.docutils) .property {\n  display: inline-block;\n  padding-right: 8px;\n}\n.rst-content .viewcode-link, .rst-content .viewcode-back {\n  display: inline-block;\n  color: #27AE60;\n  font-size: 80%;\n  padding-left: 24px;\n}\n.rst-content .viewcode-back {\n  display: block;\n  float: right;\n}\n.rst-content p.rubric {\n  margin-bottom: 12px;\n  font-weight: bold;\n}\n.rst-content tt.download, .rst-content code.download {\n  background: inherit;\n  padding: inherit;\n  font-family: inherit;\n  font-size: inherit;\n  color: inherit;\n  border: inherit;\n  white-space: inherit;\n}\n.rst-content tt.download span:first-child:before, .rst-content code.download span:first-child:before {\n  margin-right: 4px;\n}\n\n@media screen and (max-width: 480px) {\n  .rst-content .sidebar {\n    width: 100%;\n  }\n}\nspan[id*='MathJax-Span'] {\n  color: #404040;\n}\n\n.math {\n  text-align: center;\n}\n\n@font-face {\n  font-family: \"Inconsolata\";\n  font-style: normal;\n  font-weight: 400;\n  src: local(\"Inconsolata\"), local(\"Inconsolata-Regular\"), url(../fonts/Inconsolata-Regular.ttf) format(\"truetype\");\n}\n@font-face {\n  font-family: \"Inconsolata\";\n  font-style: normal;\n  font-weight: 700;\n  src: local(\"Inconsolata Bold\"), local(\"Inconsolata-Bold\"), url(../fonts/Inconsolata-Bold.ttf) format(\"truetype\");\n}\n@font-face {\n  font-family: \"Lato\";\n  font-style: normal;\n  font-weight: 400;\n  src: local(\"Lato Regular\"), local(\"Lato-Regular\"), url(../fonts/Lato-Regular.ttf) format(\"truetype\");\n}\n@font-face {\n  font-family: \"Lato\";\n  font-style: normal;\n  font-weight: 700;\n  src: local(\"Lato Bold\"), local(\"Lato-Bold\"), url(../fonts/Lato-Bold.ttf) format(\"truetype\");\n}\n@font-face {\n  font-family: \"Roboto Slab\";\n  font-style: normal;\n  font-weight: 400;\n  src: local(\"Roboto Slab Regular\"), local(\"RobotoSlab-Regular\"), url(../fonts/RobotoSlab-Regular.ttf) format(\"truetype\");\n}\n@font-face {\n  font-family: \"Roboto Slab\";\n  font-style: normal;\n  font-weight: 700;\n  src: local(\"Roboto Slab Bold\"), local(\"RobotoSlab-Bold\"), url(../fonts/RobotoSlab-Bold.ttf) format(\"truetype\");\n}\n\n/*# sourceMappingURL=theme.css.map */\n"
  },
  {
    "path": "docs/sphinx/_build/_static/doctools.js",
    "content": "/*\n * doctools.js\n * ~~~~~~~~~~~\n *\n * Sphinx JavaScript utilities for all documentation.\n *\n * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n/**\n * select a different prefix for underscore\n */\n$u = _.noConflict();\n\n/**\n * make the code below compatible with browsers without\n * an installed firebug like debugger\nif (!window.console || !console.firebug) {\n  var names = [\"log\", \"debug\", \"info\", \"warn\", \"error\", \"assert\", \"dir\",\n    \"dirxml\", \"group\", \"groupEnd\", \"time\", \"timeEnd\", \"count\", \"trace\",\n    \"profile\", \"profileEnd\"];\n  window.console = {};\n  for (var i = 0; i < names.length; ++i)\n    window.console[names[i]] = function() {};\n}\n */\n\n/**\n * small helper function to urldecode strings\n */\njQuery.urldecode = function(x) {\n  return decodeURIComponent(x).replace(/\\+/g, ' ');\n};\n\n/**\n * small helper function to urlencode strings\n */\njQuery.urlencode = encodeURIComponent;\n\n/**\n * This function returns the parsed url parameters of the\n * current request. Multiple values per key are supported,\n * it will always return arrays of strings for the value parts.\n */\njQuery.getQueryParameters = function(s) {\n  if (typeof s == 'undefined')\n    s = document.location.search;\n  var parts = s.substr(s.indexOf('?') + 1).split('&');\n  var result = {};\n  for (var i = 0; i < parts.length; i++) {\n    var tmp = parts[i].split('=', 2);\n    var key = jQuery.urldecode(tmp[0]);\n    var value = jQuery.urldecode(tmp[1]);\n    if (key in result)\n      result[key].push(value);\n    else\n      result[key] = [value];\n  }\n  return result;\n};\n\n/**\n * highlight a given string on a jquery object by wrapping it in\n * span elements with the given class name.\n */\njQuery.fn.highlightText = function(text, className) {\n  function highlight(node) {\n    if (node.nodeType == 3) {\n      var val = node.nodeValue;\n      var pos = val.toLowerCase().indexOf(text);\n      if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {\n        var span = document.createElement(\"span\");\n        span.className = className;\n        span.appendChild(document.createTextNode(val.substr(pos, text.length)));\n        node.parentNode.insertBefore(span, node.parentNode.insertBefore(\n          document.createTextNode(val.substr(pos + text.length)),\n          node.nextSibling));\n        node.nodeValue = val.substr(0, pos);\n      }\n    }\n    else if (!jQuery(node).is(\"button, select, textarea\")) {\n      jQuery.each(node.childNodes, function() {\n        highlight(this);\n      });\n    }\n  }\n  return this.each(function() {\n    highlight(this);\n  });\n};\n\n/*\n * backward compatibility for jQuery.browser\n * This will be supported until firefox bug is fixed.\n */\nif (!jQuery.browser) {\n  jQuery.uaMatch = function(ua) {\n    ua = ua.toLowerCase();\n\n    var match = /(chrome)[ \\/]([\\w.]+)/.exec(ua) ||\n      /(webkit)[ \\/]([\\w.]+)/.exec(ua) ||\n      /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec(ua) ||\n      /(msie) ([\\w.]+)/.exec(ua) ||\n      ua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec(ua) ||\n      [];\n\n    return {\n      browser: match[ 1 ] || \"\",\n      version: match[ 2 ] || \"0\"\n    };\n  };\n  jQuery.browser = {};\n  jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;\n}\n\n/**\n * Small JavaScript module for the documentation.\n */\nvar Documentation = {\n\n  init : function() {\n    this.fixFirefoxAnchorBug();\n    this.highlightSearchWords();\n    this.initIndexTable();\n    \n  },\n\n  /**\n   * i18n support\n   */\n  TRANSLATIONS : {},\n  PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },\n  LOCALE : 'unknown',\n\n  // gettext and ngettext don't access this so that the functions\n  // can safely bound to a different name (_ = Documentation.gettext)\n  gettext : function(string) {\n    var translated = Documentation.TRANSLATIONS[string];\n    if (typeof translated == 'undefined')\n      return string;\n    return (typeof translated == 'string') ? translated : translated[0];\n  },\n\n  ngettext : function(singular, plural, n) {\n    var translated = Documentation.TRANSLATIONS[singular];\n    if (typeof translated == 'undefined')\n      return (n == 1) ? singular : plural;\n    return translated[Documentation.PLURALEXPR(n)];\n  },\n\n  addTranslations : function(catalog) {\n    for (var key in catalog.messages)\n      this.TRANSLATIONS[key] = catalog.messages[key];\n    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');\n    this.LOCALE = catalog.locale;\n  },\n\n  /**\n   * add context elements like header anchor links\n   */\n  addContextElements : function() {\n    $('div[id] > :header:first').each(function() {\n      $('<a class=\"headerlink\">\\u00B6</a>').\n      attr('href', '#' + this.id).\n      attr('title', _('Permalink to this headline')).\n      appendTo(this);\n    });\n    $('dt[id]').each(function() {\n      $('<a class=\"headerlink\">\\u00B6</a>').\n      attr('href', '#' + this.id).\n      attr('title', _('Permalink to this definition')).\n      appendTo(this);\n    });\n  },\n\n  /**\n   * workaround a firefox stupidity\n   * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075\n   */\n  fixFirefoxAnchorBug : function() {\n    if (document.location.hash)\n      window.setTimeout(function() {\n        document.location.href += '';\n      }, 10);\n  },\n\n  /**\n   * highlight the search words provided in the url in the text\n   */\n  highlightSearchWords : function() {\n    var params = $.getQueryParameters();\n    var terms = (params.highlight) ? params.highlight[0].split(/\\s+/) : [];\n    if (terms.length) {\n      var body = $('div.body');\n      if (!body.length) {\n        body = $('body');\n      }\n      window.setTimeout(function() {\n        $.each(terms, function() {\n          body.highlightText(this.toLowerCase(), 'highlighted');\n        });\n      }, 10);\n      $('<p class=\"highlight-link\"><a href=\"javascript:Documentation.' +\n        'hideSearchWords()\">' + _('Hide Search Matches') + '</a></p>')\n          .appendTo($('#searchbox'));\n    }\n  },\n\n  /**\n   * init the domain index toggle buttons\n   */\n  initIndexTable : function() {\n    var togglers = $('img.toggler').click(function() {\n      var src = $(this).attr('src');\n      var idnum = $(this).attr('id').substr(7);\n      $('tr.cg-' + idnum).toggle();\n      if (src.substr(-9) == 'minus.png')\n        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');\n      else\n        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');\n    }).css('display', '');\n    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {\n        togglers.click();\n    }\n  },\n\n  /**\n   * helper function to hide the search marks again\n   */\n  hideSearchWords : function() {\n    $('#searchbox .highlight-link').fadeOut(300);\n    $('span.highlighted').removeClass('highlighted');\n  },\n\n  /**\n   * make the url absolute\n   */\n  makeURL : function(relativeURL) {\n    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;\n  },\n\n  /**\n   * get the current relative url\n   */\n  getCurrentURL : function() {\n    var path = document.location.pathname;\n    var parts = path.split(/\\//);\n    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\\//), function() {\n      if (this == '..')\n        parts.pop();\n    });\n    var url = parts.join('/');\n    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);\n  },\n\n  initOnKeyListeners: function() {\n    $(document).keyup(function(event) {\n      var activeElementType = document.activeElement.tagName;\n      // don't navigate when in search box or textarea\n      if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') {\n        switch (event.keyCode) {\n          case 37: // left\n            var prevHref = $('link[rel=\"prev\"]').prop('href');\n            if (prevHref) {\n              window.location.href = prevHref;\n              return false;\n            }\n          case 39: // right\n            var nextHref = $('link[rel=\"next\"]').prop('href');\n            if (nextHref) {\n              window.location.href = nextHref;\n              return false;\n            }\n        }\n      }\n    });\n  }\n};\n\n// quick alias for translations\n_ = Documentation.gettext;\n\n$(document).ready(function() {\n  Documentation.init();\n});"
  },
  {
    "path": "docs/sphinx/_build/_static/documentation_options.js",
    "content": "var DOCUMENTATION_OPTIONS = {\n    URL_ROOT: document.getElementById(\"documentation_options\").getAttribute('data-url_root'),\n    VERSION: '',\n    LANGUAGE: 'en',\n    COLLAPSE_INDEX: false,\n    BUILDER: 'html',\n    FILE_SUFFIX: '.html',\n    LINK_SUFFIX: '.html',\n    HAS_SOURCE: true,\n    SOURCELINK_SUFFIX: '.txt',\n    NAVIGATION_WITH_KEYS: false,\n    SHOW_SEARCH_SUMMARY: true,\n    ENABLE_SEARCH_SHORTCUTS: true,\n};"
  },
  {
    "path": "docs/sphinx/_build/_static/jquery-3.1.0.js",
    "content": "/*eslint-disable no-unused-vars*/\n/*!\n * jQuery JavaScript Library v3.1.0\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2016-07-07T21:44Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar document = window.document;\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\n\n\n\tfunction DOMEval( code, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar script = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n/* global Symbol */\n// Defining this global in .eslintrc would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.1.0\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android <=4.0 only\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = jQuery.isArray( copy ) ) ) ) {\n\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray( src ) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject( src ) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type( obj ) === \"function\";\n\t},\n\n\tisArray: Array.isArray,\n\n\tisWindow: function( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\n\t\t// As of jQuery 3.0, isNumeric is limited to\n\t\t// strings and numbers (primitives or objects)\n\t\t// that can be coerced to finite numbers (gh-2662)\n\t\tvar type = jQuery.type( obj );\n\t\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t\t// subtraction forces infinities to NaN\n\t\t\t!isNaN( obj - parseFloat( obj ) );\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\n\t\t/* eslint-disable no-unused-vars */\n\t\t// See https://github.com/eslint/eslint/issues/6125\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\n\t\t// Support: Android <=2.3 only (functionish RegExp)\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code ) {\n\t\tDOMEval( code );\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Support: IE <=9 - 11, Edge 12 - 13\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android <=4.0 only\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar tmp, args, proxy;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: Date.now,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.0\n * https://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2016-01-04\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\x80-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tdisabledAncestor = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\n\t\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\t\tsetDocument( context );\n\t\t}\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( (m = match[1]) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( (elem = context.getElementById( m )) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && (elem = newContext.getElementById( m )) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[2] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!compilerCache[ selector + \" \" ] &&\n\t\t\t\t(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\n\t\t\t\tif ( nodeType !== 1 ) {\n\t\t\t\t\tnewContext = context;\n\t\t\t\t\tnewSelector = selector;\n\n\t\t\t\t// qSA looks outside Element context, which is not what we want\n\t\t\t\t// Thanks to Andrew Dupont for this workaround technique\n\t\t\t\t// Support: IE <=8\n\t\t\t\t// Exclude object elements\n\t\t\t\t} else if ( context.nodeName.toLowerCase() !== \"object\" ) {\n\n\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\tif ( (nid = context.getAttribute( \"id\" )) ) {\n\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", (nid = expando) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = \"#\" + nid + \" \" + toSelector( groups[i] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\t\t\t\t}\n\n\t\t\t\tif ( newSelector ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement(\"fieldset\");\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\t// Known :disabled false positives:\n\t// IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset)\n\t// not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Check form elements and option elements for explicit disabling\n\t\treturn \"label\" in elem && elem.disabled === disabled ||\n\t\t\t\"form\" in elem && elem.disabled === disabled ||\n\n\t\t\t// Check non-disabled form elements for fieldset[disabled] ancestors\n\t\t\t\"form\" in elem && elem.disabled === false && (\n\t\t\t\t// Support: IE6-11+\n\t\t\t\t// Ancestry is covered for us\n\t\t\t\telem.isDisabled === disabled ||\n\n\t\t\t\t// Otherwise, assume any non-<option> under fieldset[disabled] is disabled\n\t\t\t\t/* jshint -W018 */\n\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\t(\"label\" in elem || !disabledAncestor( elem )) !== disabled\n\t\t\t);\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9-11, Edge\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\tif ( preferredDoc !== document &&\n\t\t(subWindow = document.defaultView) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( el ) {\n\t\tel.appendChild( document.createComment(\"\") );\n\t\treturn !el.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\treturn m ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( document.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( el ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll(\":enabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll(\":disabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( el ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === document ? -1 :\n\t\t\t\tb === document ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!compilerCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn (sel + \"\").replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( (oldCache = uniqueCache[ key ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context === document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\tif ( !context && elem.ownerDocument !== document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( el ) {\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement(\"fieldset\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( el ) {\n\treturn el.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;\n\t} );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn elem.contentDocument || jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnotwhite = ( /\\S+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( jQuery.isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && jQuery.type( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && jQuery.isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Support: Android 4.0 only\n\t\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\t\tresolve.call( undefined, value );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.call( undefined, value );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( jQuery.isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tjQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlen ? fn( elems[ 0 ], key ) : emptyGet;\n};\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ jQuery.camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ jQuery.camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( jQuery.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( jQuery.camelCase );\n\t\t\t} else {\n\t\t\t\tkey = jQuery.camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnotwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? JSON.parse( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tjQuery.contains( elem.ownerDocument, elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\nvar swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted,\n\t\tscale = 1,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\tdo {\n\n\t\t\t// If previous iteration zeroed out, double until we get *something*.\n\t\t\t// Use string for doubling so we don't accidentally see scale as unchanged below\n\t\t\tscale = scale || \".5\";\n\n\t\t\t// Adjust and apply\n\t\t\tinitialInUnit = initialInUnit / scale;\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t// Break the loop if scale is unchanged or perfect, or if we've just had enough.\n\t\t} while (\n\t\t\tscale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations\n\t\t);\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) ),\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i );\n\nvar rscriptType = ( /^$|\\/(?:java|ecma)script/i );\n\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// Support: IE <=9 only\n\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\n// Support: IE <=9 only\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret = typeof context.getElementsByTagName !== \"undefined\" ?\n\t\t\tcontext.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== \"undefined\" ?\n\t\t\t\tcontext.querySelectorAll( tag || \"*\" ) :\n\t\t\t[];\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], ret ) :\n\t\tret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, contains, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( contains ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n} )();\nvar documentElement = document.documentElement;\n\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 only\n// See #13393 for more info\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tvar event = jQuery.event.fix( nativeEvent );\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\t\t\thandlers = ( dataPriv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or 2) have namespace(s)\n\t\t\t\t// a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, matches, sel, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Support: IE <=9\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t//\n\t\t// Support: Firefox <=42\n\t\t// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)\n\t\tif ( delegateCount && cur.nodeType &&\n\t\t\t( event.type !== \"click\" || isNaN( event.button ) || event.button < 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== \"click\" ) ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matches } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: jQuery.isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\tthis.focus();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this.type === \"checkbox\" && this.click && jQuery.nodeName( this, \"input\" ) ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\treturn ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t/* eslint-disable max-len */\n\n\t// See https://github.com/eslint/eslint/issues/3229\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n\n\t/* eslint-enable */\n\n\t// Support: IE <=10 - 11, Edge 12 - 13\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\nfunction manipulationTarget( elem, content ) {\n\tif ( jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn elem.getElementsByTagName( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\n\tif ( match ) {\n\t\telem.type = match[ 1 ];\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.access( src );\n\t\tpdataCur = dataPriv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = concat.apply( [], args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tisFunction = jQuery.isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( isFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( isFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && jQuery.contains( node.ownerDocument, node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html.replace( rxhtmlTag, \"<$1></$2>\" );\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rmargin = ( /^margin/ );\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdiv.style.cssText =\n\t\t\t\"box-sizing:border-box;\" +\n\t\t\t\"position:relative;display:block;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"top:1%;width:50%\";\n\t\tdiv.innerHTML = \"\";\n\t\tdocumentElement.appendChild( container );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = divStyle.marginLeft === \"2px\";\n\t\tboxSizingReliableVal = divStyle.width === \"4px\";\n\n\t\t// Support: Android 4.0 - 4.3 only\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.marginRight = \"50%\";\n\t\tpixelMarginRightVal = divStyle.marginRight === \"4px\";\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tcontainer.style.cssText = \"border:0;width:8px;height:0;top:0;left:-9999px;\" +\n\t\t\"padding:0;margin-top:1px;position:absolute\";\n\tcontainer.appendChild( div );\n\n\tjQuery.extend( support, {\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelMarginRight: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelMarginRightVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// Support: IE <=9 only\n\t// getPropertyValue is only needed for .css('filter') (#12537)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style;\n\n// Return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( name ) {\n\n\t// Shortcut for names that are not vendor prefixed\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// At this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\n\t\t\t// At this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// At this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar val,\n\t\tvalueIsBorderBox = true,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// Support: IE <=11 only\n\t// Running getBoundingClientRect on a disconnected node\n\t// in IE throws an error.\n\tif ( elem.getClientRects().length ) {\n\t\tval = elem.getBoundingClientRect()[ name ];\n\t}\n\n\t// Some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test( val ) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// Check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox &&\n\t\t\t( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// Use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t\"float\": \"cssFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] ||\n\t\t\t( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\tif ( type === \"number\" ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tstyle[ name ] = value;\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] ||\n\t\t\t( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = extra && getStyles( elem ),\n\t\t\t\tsubtract = extra && augmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t);\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ name ] = value;\n\t\t\t\tvalue = jQuery.css( elem, name );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 &&\n\t\t\t\t( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction raf() {\n\tif ( timerId ) {\n\t\twindow.requestAnimationFrame( raf );\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 13\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( jQuery.isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tjQuery.proxy( result.stop, result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnotwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off or if document is hidden\n\tif ( jQuery.fx.off || document.hidden ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\topt.duration = typeof opt.duration === \"number\" ?\n\t\t\topt.duration : opt.duration in jQuery.fx.speeds ?\n\t\t\t\tjQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = window.requestAnimationFrame ?\n\t\t\twindow.requestAnimationFrame( raf ) :\n\t\t\twindow.setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tif ( window.cancelAnimationFrame ) {\n\t\twindow.cancelAnimationFrame( timerId );\n\t} else {\n\t\twindow.clearInterval( timerId );\n\t}\n\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tjQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\t\trclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t\t0 :\n\t\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( typeof value === \"string\" && value ) {\n\t\t\tclasses = value.match( rnotwhite ) || [];\n\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 &&\n\t\t\t\t\t( \" \" + curValue + \" \" ).replace( rclass, \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tif ( typeof value === \"string\" && value ) {\n\t\t\tclasses = value.match( rnotwhite ) || [];\n\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 &&\n\t\t\t\t\t( \" \" + curValue + \" \" ).replace( rclass, \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( type === \"string\" ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + getClass( elem ) + \" \" ).replace( rclass, \" \" )\n\t\t\t\t\t.indexOf( className ) > -1\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g,\n\trspaces = /[\\x20\\t\\r\\n\\f]+/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\n\t\t\t\t\t// Handle most common string cases\n\t\t\t\t\tret.replace( rreturn, \"\" ) :\n\n\t\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) ).replace( rspaces, \" \" );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || {} )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\telem[ type ]();\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n} );\n\njQuery.fn.extend( {\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\n\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = jQuery.now();\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = jQuery.isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t} ) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 13\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in uncached url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rts, \"\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce++ ) + uncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" ).prop( {\n\t\t\t\t\tcharset: s.scriptCharset,\n\t\t\t\t\tsrc: s.url\n\t\t\t\t} ).on(\n\t\t\t\t\t\"load error\",\n\t\t\t\t\tcallback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = jQuery.trim( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar docElem, win, rect, doc,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\trect = elem.getBoundingClientRect();\n\n\t\t// Make sure element is not hidden (display: none)\n\t\tif ( rect.width || rect.height ) {\n\t\t\tdoc = elem.ownerDocument;\n\t\t\twin = getWindow( doc );\n\t\t\tdocElem = doc.documentElement;\n\n\t\t\treturn {\n\t\t\t\ttop: rect.top + win.pageYOffset - docElem.clientTop,\n\t\t\t\tleft: rect.left + win.pageXOffset - docElem.clientLeft\n\t\t\t};\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden elements (gh-2310)\n\t\treturn rect;\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// Fixed elements are offset from window (parentOffset = {top:0, left: 0},\n\t\t// because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume getBoundingClientRect is there when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset = {\n\t\t\t\ttop: parentOffset.top + jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true ),\n\t\t\t\tleft: parentOffset.left + jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true )\n\t\t\t};\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t}\n} );\n\njQuery.parseJSON = JSON.parse;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( !noGlobal ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "docs/sphinx/_build/_static/jquery-3.6.0.js",
    "content": "/*!\n * jQuery JavaScript Library v3.6.0\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright OpenJS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2021-03-02T17:08Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar flat = arr.flat ? function( array ) {\n\treturn arr.flat.call( array );\n} : function( array ) {\n\treturn arr.concat.apply( [], array );\n};\n\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n\t\t// Support: Chrome <=57, Firefox <=52\n\t\t// In some browsers, typeof returns \"function\" for HTML <object> elements\n\t\t// (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n\t\t// We don't want to classify *any* DOM node as a function.\n\t\t// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5\n\t\t// Plus for old WebKit, typeof returns \"function\" for HTML collections\n\t\t// (e.g., `typeof document.getElementsByTagName(\"div\") === \"function\"`). (gh-4756)\n\t\treturn typeof obj === \"function\" && typeof obj.nodeType !== \"number\" &&\n\t\t\ttypeof obj.item !== \"function\";\n\t};\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\nvar document = window.document;\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.6.0\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teven: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn ( i + 1 ) % 2;\n\t\t} ) );\n\t},\n\n\todd: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn i % 2;\n\t\t} ) );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a provided context; falls back to the global one\n\t// if not specified.\n\tglobalEval: function( code, options, doc ) {\n\t\tDOMEval( code, { nonce: options && options.nonce }, doc );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn flat( ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\n\tfunction( _i, name ) {\n\t\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n\t} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.6\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2021-02-16\n */\n( function( window ) {\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ( {} ).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpushNative = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|\" +\n\t\t\"ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram\n\tidentifier = \"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace +\n\t\t\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\n\t\t// \"Attribute values must be CSS identifiers [capture 5]\n\t\t// or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" +\n\t\twhitespace + \"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" +\n\t\twhitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace +\n\t\t\"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" +\n\t\t\twhitespace + \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" +\n\t\t\twhitespace + \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace +\n\t\t\t\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n\t\t\t\"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace + \"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\", \"g\" ),\n\tfunescape = function( escape, nonHex ) {\n\t\tvar high = \"0x\" + escape.slice( 1 ) - 0x10000;\n\n\t\treturn nonHex ?\n\n\t\t\t// Strip the backslash prefix from a non-hex escape sequence\n\t\t\tnonHex :\n\n\t\t\t// Replace a hexadecimal escape sequence with the encoded Unicode code point\n\t\t\t// Support: IE <=11+\n\t\t\t// For values outside the Basic Multilingual Plane (BMP), manually construct a\n\t\t\t// surrogate pair\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" +\n\t\t\t\tch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t( arr = slice.call( preferredDoc.childNodes ) ),\n\t\tpreferredDoc.childNodes\n\t);\n\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\t// eslint-disable-next-line no-unused-expressions\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpushNative.apply( target, slice.call( els ) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( ( target[ j++ ] = els[ i++ ] ) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\t\tsetDocument( context );\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( ( m = match[ 1 ] ) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( ( elem = context.getElementById( m ) ) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && ( elem = newContext.getElementById( m ) ) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[ 2 ] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t( nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\" ) ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// The technique has to be used as well when a leading combinator is used\n\t\t\t\t// as such selectors are not recognized by querySelectorAll.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 &&\n\t\t\t\t\t( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\n\t\t\t\t\t// We can use :scope instead of the ID hack if the browser\n\t\t\t\t\t// supports it & if we're not changing the context.\n\t\t\t\t\tif ( newContext !== context || !support.scope ) {\n\n\t\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\t\tif ( ( nid = context.getAttribute( \"id\" ) ) ) {\n\t\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontext.setAttribute( \"id\", ( nid = expando ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[ i ] = ( nid ? \"#\" + nid : \":scope\" ) + \" \" +\n\t\t\t\t\t\t\ttoSelector( groups[ i ] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn ( cache[ key + \" \" ] = value );\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement( \"fieldset\" );\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch ( e ) {\n\t\treturn false;\n\t} finally {\n\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split( \"|\" ),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[ i ] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( ( cur = cur.nextSibling ) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn ( name === \"input\" || name === \"button\" ) && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction( function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction( function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ ( j = matchIndexes[ i ] ) ] ) {\n\t\t\t\t\tseed[ j ] = !( matches[ j ] = seed[ j ] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem && elem.namespaceURI,\n\t\tdocElem = elem && ( elem.ownerDocument || elem ).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( preferredDoc != document &&\n\t\t( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,\n\t// Safari 4 - 5 only, Opera <=11.6 - 12.x only\n\t// IE/Edge & older browsers don't support the :scope pseudo-class.\n\t// Support: Safari 6.0 only\n\t// Safari 6.0 supports :scope but it's an alias of :root there.\n\tsupport.scope = assert( function( el ) {\n\t\tdocElem.appendChild( el ).appendChild( document.createElement( \"div\" ) );\n\t\treturn typeof el.querySelectorAll !== \"undefined\" &&\n\t\t\t!el.querySelectorAll( \":scope fieldset div\" ).length;\n\t} );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert( function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute( \"className\" );\n\t} );\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert( function( el ) {\n\t\tel.appendChild( document.createComment( \"\" ) );\n\t\treturn !el.getElementsByTagName( \"*\" ).length;\n\t} );\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert( function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t} );\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[ \"ID\" ] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute( \"id\" ) === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[ \"ID\" ] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode( \"id\" );\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( ( elem = elems[ i++ ] ) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[ \"TAG\" ] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[ \"CLASS\" ] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {\n\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert( function( el ) {\n\n\t\t\tvar input;\n\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll( \"[msallowcapture^='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll( \"[selected]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"~=\" );\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 15 - 18+\n\t\t\t// IE 11/Edge don't find elements on a `[name='']` query in some cases.\n\t\t\t// Adding a temporary attribute to the document before the selection works\n\t\t\t// around the issue.\n\t\t\t// Interestingly, IE 10 & older don't seem to have the issue.\n\t\t\tinput = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"name\", \"\" );\n\t\t\tel.appendChild( input );\n\t\t\tif ( !el.querySelectorAll( \"[name='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*name\" + whitespace + \"*=\" +\n\t\t\t\t\twhitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll( \":checked\" ).length ) {\n\t\t\t\trbuggyQSA.push( \":checked\" );\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push( \".#.+[+~]\" );\n\t\t\t}\n\n\t\t\t// Support: Firefox <=3.6 - 5 only\n\t\t\t// Old Firefox doesn't throw on a badly-escaped identifier.\n\t\t\tel.querySelectorAll( \"\\\\\\f\" );\n\t\t\trbuggyQSA.push( \"[\\\\r\\\\n\\\\f]\" );\n\t\t} );\n\n\t\tassert( function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll( \"[name=d]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll( \":enabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll( \":disabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: Opera 10 - 11 only\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll( \"*,:x\" );\n\t\t\trbuggyQSA.push( \",.*:\" );\n\t\t} );\n\t}\n\n\tif ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector ) ) ) ) {\n\n\t\tassert( function( el ) {\n\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t} );\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( \"|\" ) );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( \"|\" ) );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t) );\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( ( b = b.parentNode ) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t// two documents; shallow comparisons work.\n\t\t// eslint-disable-next-line eqeqeq\n\t\tcompare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( a == document || a.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, a ) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( b == document || b.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, b ) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\treturn a == document ? -1 :\n\t\t\t\tb == document ? 1 :\n\t\t\t\t/* eslint-enable eqeqeq */\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[ i ] === bp[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[ i ], bp[ i ] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\tap[ i ] == preferredDoc ? -1 :\n\t\t\tbp[ i ] == preferredDoc ? 1 :\n\t\t\t/* eslint-enable eqeqeq */\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\tsetDocument( elem );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\n\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t// fragment in IE 9\n\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( context.ownerDocument || context ) != document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( elem.ownerDocument || elem ) != document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn ( sel + \"\" ).replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( ( node = elem[ i++ ] ) ) {\n\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[ 1 ] = match[ 1 ].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[ 3 ] = ( match[ 3 ] || match[ 4 ] ||\n\t\t\t\tmatch[ 5 ] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[ 2 ] === \"~=\" ) {\n\t\t\t\tmatch[ 3 ] = \" \" + match[ 3 ] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[ 1 ] = match[ 1 ].toLowerCase();\n\n\t\t\tif ( match[ 1 ].slice( 0, 3 ) === \"nth\" ) {\n\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[ 3 ] ) {\n\t\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[ 4 ] = +( match[ 4 ] ?\n\t\t\t\t\tmatch[ 5 ] + ( match[ 6 ] || 1 ) :\n\t\t\t\t\t2 * ( match[ 3 ] === \"even\" || match[ 3 ] === \"odd\" ) );\n\t\t\t\tmatch[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === \"odd\" );\n\n\t\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[ 3 ] ) {\n\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[ 6 ] && match[ 2 ];\n\n\t\t\tif ( matchExpr[ \"CHILD\" ].test( match[ 0 ] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[ 3 ] ) {\n\t\t\t\tmatch[ 2 ] = match[ 4 ] || match[ 5 ] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t( excess = tokenize( unquoted, true ) ) &&\n\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t( excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length ) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[ 0 ] = match[ 0 ].slice( 0, excess );\n\t\t\t\tmatch[ 2 ] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() {\n\t\t\t\t\treturn true;\n\t\t\t\t} :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t( pattern = new RegExp( \"(^|\" + whitespace +\n\t\t\t\t\t\")\" + className + \"(\" + whitespace + \"|$)\" ) ) && classCache(\n\t\t\t\t\t\tclassName, function( elem ) {\n\t\t\t\t\t\t\treturn pattern.test(\n\t\t\t\t\t\t\t\ttypeof elem.className === \"string\" && elem.className ||\n\t\t\t\t\t\t\t\ttypeof elem.getAttribute !== \"undefined\" &&\n\t\t\t\t\t\t\t\t\telem.getAttribute( \"class\" ) ||\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\t/* eslint-disable max-len */\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t\t/* eslint-enable max-len */\n\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, _argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( ( node = node[ dir ] ) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction( function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[ i ] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} ) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction( function( selector ) {\n\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction( function( seed, matches, _context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\t\t\t\t\tseed[ i ] = !( matches[ i ] = elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} ) :\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tinput[ 0 ] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[ 0 ] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t} ),\n\n\t\t\"has\": markFunction( function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t} ),\n\n\t\t\"contains\": markFunction( function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t} ),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test( lang || \"\" ) ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( ( elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute( \"xml:lang\" ) || elem.getAttribute( \"lang\" ) ) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t} ),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement &&\n\t\t\t\t( !document.hasFocus || document.hasFocus() ) &&\n\t\t\t\t!!( elem.type || elem.href || ~elem.tabIndex );\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn ( nodeName === \"input\" && !!elem.checked ) ||\n\t\t\t\t( nodeName === \"option\" && !!elem.selected );\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\t// eslint-disable-next-line no-unused-expressions\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[ \"empty\" ]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( ( attr = elem.getAttribute( \"type\" ) ) == null ||\n\t\t\t\t\tattr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo( function() {\n\t\t\treturn [ 0 ];\n\t\t} ),\n\n\t\t\"last\": createPositionalPseudo( function( _matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t} ),\n\n\t\t\"eq\": createPositionalPseudo( function( _matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t} ),\n\n\t\t\"even\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"odd\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"lt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"gt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} )\n\t}\n};\n\nExpr.pseudos[ \"nth\" ] = Expr.pseudos[ \"eq\" ];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || ( match = rcomma.exec( soFar ) ) ) {\n\t\t\tif ( match ) {\n\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[ 0 ].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( ( tokens = [] ) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( ( match = rcombinators.exec( soFar ) ) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push( {\n\t\t\t\tvalue: matched,\n\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[ 0 ].replace( rtrim, \" \" )\n\t\t\t} );\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||\n\t\t\t\t( match = preFilters[ type ]( match ) ) ) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push( {\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t} );\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[ i ].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || ( elem[ expando ] = {} );\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] ||\n\t\t\t\t\t\t\t( outerCache[ elem.uniqueID ] = {} );\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( ( oldCache = uniqueCache[ key ] ) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn ( newCache[ 2 ] = oldCache[ 2 ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[ i ]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[ 0 ];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[ i ], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction( function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts(\n\t\t\t\tselector || \"*\",\n\t\t\t\tcontext.nodeType ? [ context ] : context,\n\t\t\t\t[]\n\t\t\t),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( ( elem = temp[ i ] ) ) {\n\t\t\t\t\tmatcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) ) {\n\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( ( matcherIn[ i ] = elem ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, ( matcherOut = [] ), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) &&\n\t\t\t\t\t\t( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {\n\n\t\t\t\t\t\tseed[ temp ] = !( results[ temp ] = elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t} );\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[ 0 ].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[ \" \" ],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t( checkContext = context ).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[ j ].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\n\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\ttokens\n\t\t\t\t\t\t.slice( 0, i - 1 )\n\t\t\t\t\t\t.concat( { value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" } )\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[ \"TAG\" ]( \"*\", outermost ),\n\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\n\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\toutermostContext = context == document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\n\t\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\t\tif ( !context && elem.ownerDocument != document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( ( matcher = elementMatchers[ j++ ] ) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( ( elem = !matcher && elem ) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( ( matcher = setMatchers[ j++ ] ) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !( unmatched[ i ] || setMatched[ i ] ) ) {\n\t\t\t\t\t\t\t\tsetMatched[ i ] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[ i ] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache(\n\t\t\tselector,\n\t\t\tmatcherFromGroupMatchers( elementMatchers, setMatchers )\n\t\t);\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( ( selector = compiled.selector || selector ) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[ 0 ] = match[ 0 ].slice( 0 );\n\t\tif ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === \"ID\" &&\n\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {\n\n\t\t\tcontext = ( Expr.find[ \"ID\" ]( token.matches[ 0 ]\n\t\t\t\t.replace( runescape, funescape ), context ) || [] )[ 0 ];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[ \"needsContext\" ].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[ i ];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ ( type = token.type ) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( ( find = Expr.find[ type ] ) ) {\n\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( ( seed = find(\n\t\t\t\t\ttoken.matches[ 0 ].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext\n\t\t\t\t) ) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split( \"\" ).sort( sortOrder ).join( \"\" ) === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert( function( el ) {\n\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement( \"fieldset\" ) ) & 1;\n} );\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert( function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute( \"href\" ) === \"#\";\n} ) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert( function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n} ) ) {\n\taddHandle( \"value\", function( elem, _name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert( function( el ) {\n\treturn el.getAttribute( \"disabled\" ) == null;\n} ) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\t\tnull;\n\t\t}\n\t} );\n}\n\nreturn Sizzle;\n\n} )( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n}\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( elem.contentDocument != null &&\n\n\t\t\t// Support: IE 11+\n\t\t\t// <object> elements with no `data` attribute has an object\n\t\t\t// `contentDocument` with a `null` prototype.\n\t\t\tgetProto( elem.contentDocument ) ) {\n\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( _i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the primary Deferred\n\t\t\tprimary = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tprimary.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( primary.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn primary.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );\n\t\t}\n\n\t\treturn primary.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, _key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\t\tvalue :\n\t\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( _all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// Support: IE <=9 only\n\t// IE <=9 replaces <option> tags with their contents when inserted outside of\n\t// the select element.\n\tdiv.innerHTML = \"<option></option>\";\n\tsupport.option = !!div.lastChild;\n} )();\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: IE <=9 only\nif ( !support.option ) {\n\twrapMap.optgroup = wrapMap.option = [ 1, \"<select multiple='multiple'>\", \"</select>\" ];\n}\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\nvar rtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Only attach events to objects that accept data\n\t\tif ( !acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = Object.create( null );\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\n\t\t\t// Make a writable jQuery.Event from the native event object\n\t\t\tevent = jQuery.event.fix( nativeEvent ),\n\n\t\t\thandlers = (\n\t\t\t\tdataPriv.get( this, \"events\" ) || Object.create( null )\n\t\t\t)[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\t\t// Support: Chrome 86+\n\t\t\t\t\t\t// In Chrome, if an element having a focusout handler is blurred by\n\t\t\t\t\t\t// clicking outside of it, it invokes the handler synchronously. If\n\t\t\t\t\t\t// that handler calls `.remove()` on the element, the data is cleared,\n\t\t\t\t\t\t// leaving `result` undefined. We need to guard against this.\n\t\t\t\t\t\treturn result && result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\twhich: true\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\t// Suppress native focus or blur as it's already being fired\n\t\t// in leverageNative.\n\t\t_default: function() {\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.get( src );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdataPriv.remove( dest, \"handle events\" );\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = flat( args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t}, doc );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html;\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.call( elem );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableTrDimensionsVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t},\n\n\t\t// Support: IE 9 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Behavior in IE 9 is more subtle than in newer versions & it passes\n\t\t// some versions of this test; make sure not to make it pass there!\n\t\t//\n\t\t// Support: Firefox 70+\n\t\t// Only Firefox includes border widths\n\t\t// in computed dimensions. (gh-4529)\n\t\treliableTrDimensions: function() {\n\t\t\tvar table, tr, trChild, trStyle;\n\t\t\tif ( reliableTrDimensionsVal == null ) {\n\t\t\t\ttable = document.createElement( \"table\" );\n\t\t\t\ttr = document.createElement( \"tr\" );\n\t\t\t\ttrChild = document.createElement( \"div\" );\n\n\t\t\t\ttable.style.cssText = \"position:absolute;left:-11111px;border-collapse:separate\";\n\t\t\t\ttr.style.cssText = \"border:1px solid\";\n\n\t\t\t\t// Support: Chrome 86+\n\t\t\t\t// Height set through cssText does not get applied.\n\t\t\t\t// Computed height then comes back as 0.\n\t\t\t\ttr.style.height = \"1px\";\n\t\t\t\ttrChild.style.height = \"9px\";\n\n\t\t\t\t// Support: Android 8 Chrome 86+\n\t\t\t\t// In our bodyBackground.html iframe,\n\t\t\t\t// display for all div elements is set to \"inline\",\n\t\t\t\t// which causes a problem only in Android 8 Chrome 86.\n\t\t\t\t// Ensuring the div is display: block\n\t\t\t\t// gets around this issue.\n\t\t\t\ttrChild.style.display = \"block\";\n\n\t\t\t\tdocumentElement\n\t\t\t\t\t.appendChild( table )\n\t\t\t\t\t.appendChild( tr )\n\t\t\t\t\t.appendChild( trChild );\n\n\t\t\t\ttrStyle = window.getComputedStyle( tr );\n\t\t\t\treliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderTopWidth, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;\n\n\t\t\t\tdocumentElement.removeChild( table );\n\t\t\t}\n\t\t\treturn reliableTrDimensionsVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( _elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Support: IE 9 - 11 only\n\t// Use offsetWidth/offsetHeight for when box sizing is unreliable.\n\t// In those cases, the computed value can be trusted to be border-box.\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\n\t\t// Support: IE 10 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Interestingly, in some cases IE 9 doesn't suffer from this issue.\n\t\t!support.reliableTrDimensions() && nodeName( elem, \"tr\" ) ||\n\n\t\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t\t// This happens for inline elements with no explicit setting (gh-3571)\n\t\tval === \"auto\" ||\n\n\t\t// Support: Android <=4.1 - 4.3 only\n\t\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\n\t\t// Make sure the element is visible & connected\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( _i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t} ) :\n\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\n\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( _i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( _i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || Object.create( null ) )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\n\t\t\t\t// Handle: regular nodes (via `this.ownerDocument`), window\n\t\t\t\t// (via `this.document`) & document (via `this`).\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = { guid: Date.now() };\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, parserErrorElem;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {}\n\n\tparserErrorElem = xml && xml.getElementsByTagName( \"parsererror\" )[ 0 ];\n\tif ( !xml || parserErrorElem ) {\n\t\tjQuery.error( \"Invalid XML: \" + (\n\t\t\tparserErrorElem ?\n\t\t\t\tjQuery.map( parserErrorElem.childNodes, function( el ) {\n\t\t\t\t\treturn el.textContent;\n\t\t\t\t} ).join( \"\\n\" ) :\n\t\t\t\tdata\n\t\t) );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} ).filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} ).map( function( _i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\noriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce.guid++ ) +\n\t\t\t\t\tuncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Use a noop converter for missing script but not if jsonp\n\t\t\tif ( !isSuccess &&\n\t\t\t\tjQuery.inArray( \"script\", s.dataTypes ) > -1 &&\n\t\t\t\tjQuery.inArray( \"json\", s.dataTypes ) < 0 ) {\n\t\t\t\ts.converters[ \"text script\" ] = function() {};\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( _i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\njQuery.ajaxPrefilter( function( s ) {\n\tvar i;\n\tfor ( i in s.headers ) {\n\t\tif ( i.toLowerCase() === \"content-type\" ) {\n\t\t\ts.contentType = s.headers[ i ] || \"\";\n\t\t}\n\t}\n} );\n\n\njQuery._evalUrl = function( url, options, doc ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options, doc );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( \"load error\", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce.guid++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( _i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( {\n\t\tpadding: \"inner\" + name,\n\t\tcontent: type,\n\t\t\"\": \"outer\" + name\n\t}, function( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( _i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\njQuery.each(\n\t( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( _i, name ) {\n\n\t\t// Handle event binding\n\t\tjQuery.fn[ name ] = function( data, fn ) {\n\t\t\treturn arguments.length > 0 ?\n\t\t\t\tthis.on( name, null, data, fn ) :\n\t\t\t\tthis.trigger( name );\n\t\t};\n\t}\n);\n\n\n\n\n// Support: Android <=4.0 only\n// Make sure we trim BOM and NBSP\nvar rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\njQuery.trim = function( text ) {\n\treturn text == null ?\n\t\t\"\" :\n\t\t( text + \"\" ).replace( rtrim, \"\" );\n};\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === \"undefined\" ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "docs/sphinx/_build/_static/jquery.js",
    "content": "/*! jQuery v3.1.0 | (c) jQuery Foundation | jquery.org/license */\n!function(a,b){\"use strict\";\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error(\"jQuery requires a window with a document\");return b(a)}:b(a)}(\"undefined\"!=typeof window?window:this,function(a,b){\"use strict\";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement(\"script\");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q=\"3.1.0\",r=function(a,b){return new r.fn.init(a,b)},s=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?a<0?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for(\"boolean\"==typeof g&&(j=g,g=arguments[h]||{},h++),\"object\"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:\"jQuery\"+(q+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return\"function\"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return(\"number\"===b||\"string\"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||\"[object Object]\"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,\"constructor\")&&b.constructor,\"function\"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+\"\":\"object\"==typeof a||\"function\"==typeof a?j[k.call(a)]||\"object\":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,\"ms-\").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?\"\":(a+\"\").replace(s,\"\")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,\"string\"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if(\"string\"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),\"function\"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(a,b){j[\"[object \"+b+\"]\"]=b.toLowerCase()});function w(a){var b=!!a&&\"length\"in a&&a.length,c=r.type(a);return\"function\"!==c&&!r.isWindow(a)&&(\"array\"===c||0===b||\"number\"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u=\"sizzle\"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",K=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",L=\"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",M=\"\\\\[\"+K+\"*(\"+L+\")(?:\"+K+\"*([*^$|!~]?=)\"+K+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+L+\"))|)\"+K+\"*\\\\]\",N=\":(\"+L+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+M+\")*)|.*)\\\\)|)\",O=new RegExp(K+\"+\",\"g\"),P=new RegExp(\"^\"+K+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+K+\"+$\",\"g\"),Q=new RegExp(\"^\"+K+\"*,\"+K+\"*\"),R=new RegExp(\"^\"+K+\"*([>+~]|\"+K+\")\"+K+\"*\"),S=new RegExp(\"=\"+K+\"*([^\\\\]'\\\"]*?)\"+K+\"*\\\\]\",\"g\"),T=new RegExp(N),U=new RegExp(\"^\"+L+\"$\"),V={ID:new RegExp(\"^#(\"+L+\")\"),CLASS:new RegExp(\"^\\\\.(\"+L+\")\"),TAG:new RegExp(\"^(\"+L+\"|[*])\"),ATTR:new RegExp(\"^\"+M),PSEUDO:new RegExp(\"^\"+N),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+K+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+K+\"*(?:([+-]|)\"+K+\"*(\\\\d+)|))\"+K+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+J+\")$\",\"i\"),needsContext:new RegExp(\"^\"+K+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+K+\"*((?:-\\\\d)?\\\\d*)\"+K+\"*\\\\)|)(?=[^-]|$)\",\"i\")},W=/^(?:input|select|textarea|button)$/i,X=/^h\\d$/i,Y=/^[^{]+\\{\\s*\\[native \\w/,Z=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,$=/[+~]/,_=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+K+\"?|(\"+K+\")|.)\",\"ig\"),aa=function(a,b,c){var d=\"0x\"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\x80-\\uFFFF\\w-]/g,ca=function(a,b){return b?\"\\0\"===a?\"\\ufffd\":a.slice(0,-1)+\"\\\\\"+a.charCodeAt(a.length-1).toString(16)+\" \":\"\\\\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:\"parentNode\",next:\"legend\"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],\"string\"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+\" \"]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if(\"object\"!==b.nodeName.toLowerCase()){(k=b.getAttribute(\"id\"))?k=k.replace(ba,ca):b.setAttribute(\"id\",k=u),o=g(a),h=o.length;while(h--)o[h]=\"#\"+k+\" \"+sa(o[h]);r=o.join(\",\"),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute(\"id\")}}}return i(a.replace(P,\"$1\"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+\" \")>d.cacheLength&&delete b[a.shift()],b[c+\" \"]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement(\"fieldset\");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split(\"|\"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return\"input\"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return(\"input\"===c||\"button\"===c)&&b.type===a}}function oa(a){return function(b){return\"label\"in b&&b.disabled===a||\"form\"in b&&b.disabled===a||\"form\"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&(\"label\"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&\"undefined\"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&\"HTML\"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener(\"unload\",da,!1):e.attachEvent&&e.attachEvent(\"onunload\",da)),c.attributes=ja(function(a){return a.className=\"i\",!a.getAttribute(\"className\")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment(\"\")),!a.getElementsByTagName(\"*\").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(\"undefined\"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute(\"id\")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c=\"undefined\"!=typeof a.getAttributeNode&&a.getAttributeNode(\"id\");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return\"undefined\"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if(\"*\"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if(\"undefined\"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML=\"<a id='\"+u+\"'></a><select id='\"+u+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",a.querySelectorAll(\"[msallowcapture^='']\").length&&q.push(\"[*^$]=\"+K+\"*(?:''|\\\"\\\")\"),a.querySelectorAll(\"[selected]\").length||q.push(\"\\\\[\"+K+\"*(?:value|\"+J+\")\"),a.querySelectorAll(\"[id~=\"+u+\"-]\").length||q.push(\"~=\"),a.querySelectorAll(\":checked\").length||q.push(\":checked\"),a.querySelectorAll(\"a#\"+u+\"+*\").length||q.push(\".#.+[+~]\")}),ja(function(a){a.innerHTML=\"<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>\";var b=n.createElement(\"input\");b.setAttribute(\"type\",\"hidden\"),a.appendChild(b).setAttribute(\"name\",\"D\"),a.querySelectorAll(\"[name=d]\").length&&q.push(\"name\"+K+\"*[*^$|!~]?=\"),2!==a.querySelectorAll(\":enabled\").length&&q.push(\":enabled\",\":disabled\"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(\":disabled\").length&&q.push(\":enabled\",\":disabled\"),a.querySelectorAll(\"*,:x\"),q.push(\",.*:\")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,\"*\"),s.call(a,\"[s!='']:x\"),r.push(\"!=\",N)}),q=q.length&&new RegExp(q.join(\"|\")),r=r.length&&new RegExp(r.join(\"|\")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,\"='$1']\"),c.matchesSelector&&p&&!A[b+\" \"]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+\"\").replace(ba,ca)},ga.error=function(a){throw new Error(\"Syntax error, unrecognized expression: \"+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c=\"\",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if(\"string\"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||\"\").replace(_,aa),\"~=\"===a[2]&&(a[3]=\" \"+a[3]+\" \"),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),\"nth\"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*(\"even\"===a[3]||\"odd\"===a[3])),a[5]=+(a[7]+a[8]||\"odd\"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||\"\":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(\")\",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return\"*\"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+\" \"];return b||(b=new RegExp(\"(^|\"+K+\")\"+a+\"(\"+K+\"|$)\"))&&y(a,function(a){return b.test(\"string\"==typeof a.className&&a.className||\"undefined\"!=typeof a.getAttribute&&a.getAttribute(\"class\")||\"\")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?\"!=\"===b:!b||(e+=\"\",\"=\"===b?e===c:\"!=\"===b?e!==c:\"^=\"===b?c&&0===e.indexOf(c):\"*=\"===b?c&&e.indexOf(c)>-1:\"$=\"===b?c&&e.slice(-c.length)===c:\"~=\"===b?(\" \"+e.replace(O,\" \")+\" \").indexOf(c)>-1:\"|=\"===b&&(e===c||e.slice(0,c.length+1)===c+\"-\"))}},CHILD:function(a,b,c,d,e){var f=\"nth\"!==a.slice(0,3),g=\"last\"!==a.slice(-4),h=\"of-type\"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?\"nextSibling\":\"previousSibling\",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p=\"only\"===a&&!o&&\"nextSibling\"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error(\"unsupported pseudo: \"+a);return e[u]?e(b):e.length>1?(c=[a,a,\"\",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,\"$1\"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||\"\")||ga.error(\"unsupported lang: \"+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute(\"xml:lang\")||b.getAttribute(\"lang\"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+\"-\");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&!!a.checked||\"option\"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&\"button\"===a.type||\"button\"===b},text:function(a){var b;return\"input\"===a.nodeName.toLowerCase()&&\"text\"===a.type&&(null==(b=a.getAttribute(\"type\"))||\"text\"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+\" \"];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P,\" \")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d=\"\";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&\"parentNode\"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e)}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||\"*\",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[\" \"],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:\" \"===a[i-2].type?\"*\":\"\"})).replace(P,\"$1\"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s=\"0\",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG(\"*\",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+\" \"];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n=\"function\"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&\"ID\"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split(\"\").sort(B).join(\"\")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement(\"fieldset\"))}),ja(function(a){return a.innerHTML=\"<a href='#'></a>\",\"#\"===a.firstChild.getAttribute(\"href\")})||ka(\"type|href|height|width\",function(a,b,c){if(!c)return a.getAttribute(b,\"type\"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML=\"<input/>\",a.firstChild.setAttribute(\"value\",\"\"),\"\"===a.firstChild.getAttribute(\"value\")})||ka(\"value\",function(a,b,c){if(!c&&\"input\"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute(\"disabled\")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[\":\"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i,C=/^.[^:#\\[\\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if(\"string\"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=\":not(\"+a+\")\"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if(\"string\"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,\"string\"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,\"string\"==typeof a){if(e=\"<\"===a[0]&&\">\"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g=\"string\"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?\"string\"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,\"parentNode\")},parentsUntil:function(a,b,c){return y(a,\"parentNode\",c)},next:function(a){return J(a,\"nextSibling\")},prev:function(a){return J(a,\"previousSibling\")},nextAll:function(a){return y(a,\"nextSibling\")},prevAll:function(a){return y(a,\"previousSibling\")},nextUntil:function(a,b,c){return y(a,\"nextSibling\",c)},prevUntil:function(a,b,c){return y(a,\"previousSibling\",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return\"Until\"!==a.slice(-5)&&(d=c),d&&\"string\"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a=\"string\"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:\"\")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&\"string\"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c=\"\",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=\"\"),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[[\"notify\",\"progress\",r.Callbacks(\"memory\"),r.Callbacks(\"memory\"),2],[\"resolve\",\"done\",r.Callbacks(\"once memory\"),r.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",r.Callbacks(\"once memory\"),r.Callbacks(\"once memory\"),1,\"rejected\"]],d=\"pending\",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},\"catch\":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+\"With\"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError(\"Thenable self-resolution\");j=a&&(\"object\"==typeof a||\"function\"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+\"With\"](this===f?void 0:this,arguments),this},f[b[0]+\"With\"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),\"pending\"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn(\"jQuery.Deferred exception: \"+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)[\"catch\"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener(\"DOMContentLoaded\",R),a.removeEventListener(\"load\",R),r.ready()}\"complete\"===d.readyState||\"loading\"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener(\"DOMContentLoaded\",R),a.addEventListener(\"load\",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if(\"object\"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,\nr.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if(\"string\"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&\"string\"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,Y=/[A-Z]/g;function Z(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d=\"data-\"+b.replace(Y,\"-$&\").toLowerCase(),c=a.getAttribute(d),\"string\"==typeof c){try{c=\"true\"===c||\"false\"!==c&&(\"null\"===c?null:+c+\"\"===c?+c:X.test(c)?JSON.parse(c):c)}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,\"hasDataAttrs\"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf(\"data-\")&&(d=r.camelCase(d.slice(5)),Z(f,d,e[d])));V.set(f,\"hasDataAttrs\",!0)}return e}return\"object\"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=Z(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||\"fx\")+\"queue\",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||\"fx\";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};\"inprogress\"===e&&(e=c.shift(),d--),e&&(\"fx\"===b&&c.unshift(\"inprogress\"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+\"queueHooks\";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks(\"once memory\").add(function(){V.remove(a,[b+\"queue\",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return\"string\"!=typeof a&&(b=a,a=\"fx\",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),\"fx\"===a&&\"inprogress\"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||\"fx\",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};\"string\"!=typeof a&&(b=a,a=void 0),a=a||\"fx\";while(g--)c=V.get(f[g],a+\"queueHooks\"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var $=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,_=new RegExp(\"^(?:([+-])=|)(\"+$+\")([a-z%]*)$\",\"i\"),aa=[\"Top\",\"Right\",\"Bottom\",\"Left\"],ba=function(a,b){return a=b||a,\"none\"===a.style.display||\"\"===a.style.display&&r.contains(a.ownerDocument,a)&&\"none\"===r.css(a,\"display\")},ca=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function da(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,\"\")},i=h(),j=c&&c[3]||(r.cssNumber[b]?\"\":\"px\"),k=(r.cssNumber[b]||\"px\"!==j&&+i)&&_.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||\".5\",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ea={};function fa(a){var b,c=a.ownerDocument,d=a.nodeName,e=ea[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,\"display\"),b.parentNode.removeChild(b),\"none\"===e&&(e=\"block\"),ea[d]=e,e)}function ga(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?(\"none\"===c&&(e[f]=V.get(d,\"display\")||null,e[f]||(d.style.display=\"\")),\"\"===d.style.display&&ba(d)&&(e[f]=fa(d))):\"none\"!==c&&(e[f]=\"none\",V.set(d,\"display\",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ga(this,!0)},hide:function(){return ga(this)},toggle:function(a){return\"boolean\"==typeof a?a?this.show():this.hide():this.each(function(){ba(this)?r(this).show():r(this).hide()})}});var ha=/^(?:checkbox|radio)$/i,ia=/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i,ja=/^$|\\/(?:java|ecma)script/i,ka={option:[1,\"<select multiple='multiple'>\",\"</select>\"],thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c=\"undefined\"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||\"*\"):\"undefined\"!=typeof a.querySelectorAll?a.querySelectorAll(b||\"*\"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;c<d;c++)V.set(a[c],\"globalEval\",!b||V.get(b[c],\"globalEval\"))}var na=/<|&#?\\w+;/;function oa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if(\"object\"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(na.test(f)){g=g||l.appendChild(b.createElement(\"div\")),h=(ia.exec(f)||[\"\",\"\"])[1].toLowerCase(),i=ka[h]||ka._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=\"\"}else m.push(b.createTextNode(f));l.textContent=\"\",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),\"script\"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||\"\")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement(\"div\")),c=d.createElement(\"input\");c.setAttribute(\"type\",\"radio\"),c.setAttribute(\"checked\",\"checked\"),c.setAttribute(\"name\",\"t\"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML=\"<textarea>x</textarea>\",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if(\"object\"==typeof b){\"string\"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&(\"string\"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return\"undefined\"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||\"\").match(K)||[\"\"],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||\"\").split(\".\").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(\".\")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||\"\").match(K)||[\"\"],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||\"\").split(\".\").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp(\"(^|\\\\.)\"+o.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&(\"**\"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,\"handle events\")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,\"events\")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(\"click\"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||\"click\"!==a.type)){for(d=[],c=0;c<h;c++)f=b[c],e=f.selector+\" \",void 0===d[e]&&(d[e]=f.needsContext?r(e,this).index(i)>-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==va()&&this.focus)return this.focus(),!1},delegateType:\"focusin\"},blur:{trigger:function(){if(this===va()&&this.blur)return this.blur(),!1},delegateType:\"focusout\"},click:{trigger:function(){if(\"checkbox\"===this.type&&this.click&&r.nodeName(this,\"input\"))return this.click(),!1},_default:function(a){return r.nodeName(a.target,\"a\")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ta:ua,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:ua,isPropagationStopped:ua,isImmediatePropagationStopped:ua,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ta,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ta,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ta,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,\"char\":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&qa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ra.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return wa(this,a,b,c,d)},one:function(a,b,c,d){return wa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+\".\"+d.namespace:d.origType,d.selector,d.handler),this;if(\"object\"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&\"function\"!=typeof b||(c=b,b=void 0),c===!1&&(c=ua),this.each(function(){r.event.remove(this,a,c,b)})}});var xa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,ya=/<script|<style|<link/i,za=/checked\\s*(?:[^=]|=\\s*.checked.)/i,Aa=/^true\\/(.*)/,Ba=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;function Ca(a,b){return r.nodeName(a,\"table\")&&r.nodeName(11!==b.nodeType?b:b.firstChild,\"tr\")?a.getElementsByTagName(\"tbody\")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute(\"type\"))+\"/\"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute(\"type\"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ga(a,b){var c=b.nodeName.toLowerCase();\"input\"===c&&ha.test(a.type)?b.checked=a.checked:\"input\"!==c&&\"textarea\"!==c||(b.defaultValue=a.defaultValue)}function Ha(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&\"string\"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,\"script\"),Da),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,la(j,\"script\"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ea),l=0;l<i;l++)j=h[l],ja.test(j.type||\"\")&&!V.access(j,\"globalEval\")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ba,\"\"),k))}return a}function Ia(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(la(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&ma(la(d,\"script\")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(xa,\"<$1></$2>\")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;d<e;d++)Ga(f[d],g[d]);if(b)if(c)for(f=f||la(a),g=g||la(h),d=0,e=f.length;d<e;d++)Fa(f[d],g[d]);else Fa(a,h);return g=la(h,\"script\"),g.length>0&&ma(g,!i&&la(a,\"script\")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(a,!1)),a.textContent=\"\");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if(\"string\"==typeof a&&!ya.test(a)&&!ka[(ia.exec(a)||[\"\",\"\"])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(la(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(la(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ja=/^margin/,Ka=new RegExp(\"^(\"+$+\")(?!px)[a-z%]+$\",\"i\"),La=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText=\"box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",i.innerHTML=\"\",pa.appendChild(h);var b=a.getComputedStyle(i);c=\"1%\"!==b.top,g=\"2px\"===b.marginLeft,e=\"4px\"===b.width,i.style.marginRight=\"50%\",f=\"4px\"===b.marginRight,pa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement(\"div\"),i=d.createElement(\"div\");i.style&&(i.style.backgroundClip=\"content-box\",i.cloneNode(!0).style.backgroundClip=\"\",o.clearCloneStyle=\"content-box\"===i.style.backgroundClip,h.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Ma(a,b,c){var d,e,f,g,h=a.style;return c=c||La(a),c&&(g=c.getPropertyValue(b)||c[b],\"\"!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ka.test(g)&&Ja.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+\"\":g}function Na(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Oa=/^(none|table(?!-c[ea]).+)/,Pa={position:\"absolute\",visibility:\"hidden\",display:\"block\"},Qa={letterSpacing:\"0\",fontWeight:\"400\"},Ra=[\"Webkit\",\"Moz\",\"ms\"],Sa=d.createElement(\"div\").style;function Ta(a){if(a in Sa)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ra.length;while(c--)if(a=Ra[c]+b,a in Sa)return a}function Ua(a,b,c){var d=_.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||\"px\"):b}function Va(a,b,c,d,e){for(var f=c===(d?\"border\":\"content\")?4:\"width\"===b?1:0,g=0;f<4;f+=2)\"margin\"===c&&(g+=r.css(a,c+aa[f],!0,e)),d?(\"content\"===c&&(g-=r.css(a,\"padding\"+aa[f],!0,e)),\"margin\"!==c&&(g-=r.css(a,\"border\"+aa[f]+\"Width\",!0,e))):(g+=r.css(a,\"padding\"+aa[f],!0,e),\"padding\"!==c&&(g+=r.css(a,\"border\"+aa[f]+\"Width\",!0,e)));return g}function Wa(a,b,c){var d,e=!0,f=La(a),g=\"border-box\"===r.css(a,\"boxSizing\",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),d<=0||null==d){if(d=Ma(a,b,f),(d<0||null==d)&&(d=a.style[b]),Ka.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Va(a,b,c||(g?\"border\":\"content\"),e,f)+\"px\"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ma(a,\"opacity\");return\"\"===c?\"1\":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":\"cssFloat\"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&\"get\"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,\"string\"===f&&(e=_.exec(c))&&e[1]&&(c=da(a,b,e),f=\"number\"),null!=c&&c===c&&(\"number\"===f&&(c+=e&&e[3]||(r.cssNumber[h]?\"\":\"px\")),o.clearCloneStyle||\"\"!==c||0!==b.indexOf(\"background\")||(i[b]=\"inherit\"),g&&\"set\"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&\"get\"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Ma(a,b,d)),\"normal\"===e&&b in Qa&&(e=Qa[b]),\"\"===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each([\"height\",\"width\"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Oa.test(r.css(a,\"display\"))||a.getClientRects().length&&a.getBoundingClientRect().width?Wa(a,b,d):ca(a,Pa,function(){return Wa(a,b,d)})},set:function(a,c,d){var e,f=d&&La(a),g=d&&Va(a,b,d,\"border-box\"===r.css(a,\"boxSizing\",!1,f),f);return g&&(e=_.exec(c))&&\"px\"!==(e[3]||\"px\")&&(a.style[b]=c,c=r.css(a,b)),Ua(a,c,g)}}}),r.cssHooks.marginLeft=Na(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Ma(a,\"marginLeft\"))||a.getBoundingClientRect().left-ca(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+\"px\"}),r.each({margin:\"\",padding:\"\",border:\"Width\"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f=\"string\"==typeof c?c.split(\" \"):[c];d<4;d++)e[a+aa[d]+b]=f[d]||f[d-2]||f[0];return e}},Ja.test(a)||(r.cssHooks[a+b].set=Ua)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=La(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?\"\":\"px\")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,\"\"),b&&\"auto\"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:\"swing\"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=aa[d],e[\"margin\"+c]=e[\"padding\"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners[\"*\"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function eb(a,b,c){var d,e,f,g,h,i,j,k,l=\"width\"in b||\"height\"in b,m=this,n={},o=a.style,p=a.nodeType&&ba(a),q=V.get(a,\"fxshow\");c.queue||(g=r._queueHooks(a,\"fx\"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,\"fx\").length||g.empty.fire()})}));for(d in b)if(e=b[d],$a.test(e)){if(delete b[d],f=f||\"toggle\"===e,e===(p?\"hide\":\"show\")){if(\"show\"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,\"display\")),k=r.css(a,\"display\"),\"none\"===k&&(j?k=j:(ga([a],!0),j=a.style.display||j,k=r.css(a,\"display\"),ga([a]))),(\"inline\"===k||\"inline-block\"===k&&null!=j)&&\"none\"===r.css(a,\"float\")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j=\"none\"===k?\"\":k)),o.display=\"inline-block\")),c.overflow&&(o.overflow=\"hidden\",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?\"hidden\"in q&&(p=q.hidden):q=V.access(a,\"fxshow\",{display:j}),f&&(q.hidden=!p),p&&ga([a],!0),m.done(function(){p||ga([a]),V.remove(a,\"fxshow\");for(d in n)r.style(a,d,n[d])})),i=db(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function fb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&\"expand\"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function gb(a,b,c){var d,e,f=0,g=gb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Ya||bb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Ya||bb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(fb(k,j.opts.specialEasing);f<g;f++)if(d=gb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,db,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(gb,{tweeners:{\"*\":[function(a,b){var c=this.createTween(a,b);return da(c.elem,a,_.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=[\"*\"]):a=a.match(K);for(var c,d=0,e=a.length;d<e;d++)c=a[d],gb.tweeners[c]=gb.tweeners[c]||[],gb.tweeners[c].unshift(b)},prefilters:[eb],prefilter:function(a,b){b?gb.prefilters.unshift(a):gb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&\"object\"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:e.duration=\"number\"==typeof e.duration?e.duration:e.duration in r.fx.speeds?r.fx.speeds[e.duration]:r.fx.speeds._default,null!=e.queue&&e.queue!==!0||(e.queue=\"fx\"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ba).css(\"opacity\",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=gb(this,r.extend({},a),f);(e||V.get(this,\"finish\"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return\"string\"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||\"fx\",[]),this.each(function(){var b=!0,e=null!=a&&a+\"queueHooks\",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&_a.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||\"fx\"),this.each(function(){var b,c=V.get(this),d=c[a+\"queue\"],e=c[a+\"queueHooks\"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each([\"toggle\",\"show\",\"hide\"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||\"boolean\"==typeof a?c.apply(this,arguments):this.animate(cb(b,!0),a,d,e)}}),r.each({slideDown:cb(\"show\"),slideUp:cb(\"hide\"),slideToggle:cb(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Ya=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),Ya=void 0},r.fx.timer=function(a){r.timers.push(a),a()?r.fx.start():r.timers.pop()},r.fx.interval=13,r.fx.start=function(){Za||(Za=a.requestAnimationFrame?a.requestAnimationFrame(ab):a.setInterval(r.fx.tick,r.fx.interval))},r.fx.stop=function(){a.cancelAnimationFrame?a.cancelAnimationFrame(Za):a.clearInterval(Za),Za=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||\"fx\",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement(\"input\"),b=d.createElement(\"select\"),c=b.appendChild(d.createElement(\"option\"));a.type=\"checkbox\",o.checkOn=\"\"!==a.value,o.optSelected=c.selected,a=d.createElement(\"input\"),a.value=\"t\",a.type=\"radio\",o.radioValue=\"t\"===a.value}();var hb,ib=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return S(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return\"undefined\"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+\"\"),c):e&&\"get\"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&\"radio\"===b&&r.nodeName(a,\"input\")){var c=a.value;return a.setAttribute(\"type\",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);\nif(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&\"get\"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,\"tabindex\");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\\t\\r\\n\\f]/g;function mb(a){return a.getAttribute&&a.getAttribute(\"class\")||\"\"}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if(\"string\"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(\" \"+e+\" \").replace(lb,\" \")){g=0;while(f=b[g++])d.indexOf(\" \"+f+\" \")<0&&(d+=f+\" \");h=r.trim(d),e!==h&&c.setAttribute(\"class\",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(\" \"+e+\" \").replace(lb,\" \")){g=0;while(f=b[g++])while(d.indexOf(\" \"+f+\" \")>-1)d=d.replace(\" \"+f+\" \",\" \");h=r.trim(d),e!==h&&c.setAttribute(\"class\",h)}}return this},toggleClass:function(a,b){var c=typeof a;return\"boolean\"==typeof b&&\"string\"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if(\"string\"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&\"boolean\"!==c||(b=mb(this),b&&V.set(this,\"__className__\",b),this.setAttribute&&this.setAttribute(\"class\",b||a===!1?\"\":V.get(this,\"__className__\")||\"\"))})},hasClass:function(a){var b,c,d=0;b=\" \"+a+\" \";while(c=this[d++])if(1===c.nodeType&&(\" \"+mb(c)+\" \").replace(lb,\" \").indexOf(b)>-1)return!0;return!1}});var nb=/\\r/g,ob=/[\\x20\\t\\r\\n\\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e=\"\":\"number\"==typeof e?e+=\"\":r.isArray(e)&&(e=r.map(e,function(a){return null==a?\"\":a+\"\"})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&\"set\"in b&&void 0!==b.set(this,e,\"value\")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&\"get\"in b&&void 0!==(c=b.get(e,\"value\"))?c:(c=e.value,\"string\"==typeof c?c.replace(nb,\"\"):null==c?\"\":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,\"value\");return null!=b?b:r.trim(r.text(a)).replace(ob,\" \")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f=\"select-one\"===a.type,g=f?null:[],h=f?e+1:d.length,i=e<0?h:f?e:0;i<h;i++)if(c=d[i],(c.selected||i===e)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,\"optgroup\"))){if(b=r(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each([\"radio\",\"checkbox\"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute(\"value\")?\"on\":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,\"type\")?b.type:b,q=l.call(b,\"namespace\")?b.namespace.split(\".\"):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(\".\")>-1&&(q=p.split(\".\"),p=q.shift(),q.sort()),k=p.indexOf(\":\")<0&&\"on\"+p,b=b[r.expando]?b:new r.Event(p,\"object\"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join(\".\"),b.rnamespace=b.namespace?new RegExp(\"(^|\\\\.)\"+q.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,\"events\")||{})[b.type]&&V.get(h,\"handle\"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin=\"onfocusin\"in a,o.focusin||r.each({focus:\"focusin\",blur:\"focusout\"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\\?/;r.parseXML=function(b){var c;if(!b||\"string\"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,\"text/xml\")}catch(d){c=void 0}return c&&!c.getElementsByTagName(\"parsererror\").length||r.error(\"Invalid XML: \"+b),c};var tb=/\\[\\]$/,ub=/\\r?\\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+\"[\"+(\"object\"==typeof e&&null!=e?b:\"\")+\"]\",e,c,d)});else if(c||\"object\"!==r.type(b))d(a,b);else for(e in b)xb(a+\"[\"+e+\"]\",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+\"=\"+encodeURIComponent(null==c?\"\":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join(\"&\")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,\"elements\");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(\":disabled\")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,\"\\r\\n\")}}):{name:b.name,value:c.replace(ub,\"\\r\\n\")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\\/\\//,Fb={},Gb={},Hb=\"*/\".concat(\"*\"),Ib=d.createElement(\"a\");Ib.href=qb.href;function Jb(a){return function(b,c){\"string\"!=typeof b&&(c=b,b=\"*\");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])\"+\"===d[0]?(d=d.slice(1)||\"*\",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return\"string\"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e[\"*\"]&&g(\"*\")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while(\"*\"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader(\"Content-Type\"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+\" \"+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if(\"*\"===f)f=i;else if(\"*\"!==i&&i!==f){if(g=j[i+\" \"+f]||j[\"* \"+f],!g)for(e in j)if(h=e.split(\" \"),h[1]===f&&(g=j[i+\" \"+h[0]]||j[\"* \"+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a[\"throws\"])b=g(b);else try{b=g(b)}catch(l){return{state:\"parsererror\",error:g?l:\"No conversion from \"+i+\" to \"+f}}}return{state:\"success\",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:\"GET\",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Hb,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){\"object\"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks(\"once memory\"),u=o.statusCode||{},v={},w={},x=\"canceled\",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+\"\").replace(Eb,qb.protocol+\"//\"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||\"*\").toLowerCase().match(K)||[\"\"],null==o.crossDomain){j=d.createElement(\"a\");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+\"//\"+Ib.host!=j.protocol+\"//\"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&\"string\"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger(\"ajaxStart\"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,\"\"),o.hasContent?o.data&&o.processData&&0===(o.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(o.data=o.data.replace(yb,\"+\")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?\"&\":\"?\")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,\"\"),n=(sb.test(f)?\"&\":\"?\")+\"_=\"+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader(\"If-Modified-Since\",r.lastModified[f]),r.etag[f]&&y.setRequestHeader(\"If-None-Match\",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader(\"Content-Type\",o.contentType),y.setRequestHeader(\"Accept\",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+(\"*\"!==o.dataTypes[0]?\", \"+Hb+\"; q=0.01\":\"\"):o.accepts[\"*\"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x=\"abort\",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger(\"ajaxSend\",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort(\"timeout\")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,\"No Transport\");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||\"\",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader(\"Last-Modified\"),w&&(r.lastModified[f]=w),w=y.getResponseHeader(\"etag\"),w&&(r.etag[f]=w)),204===b||\"HEAD\"===o.type?x=\"nocontent\":304===b?x=\"notmodified\":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x=\"error\",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+\"\",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?\"ajaxSuccess\":\"ajaxError\",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger(\"ajaxComplete\",[y,o]),--r.active||r.event.trigger(\"ajaxStop\")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,\"json\")},getScript:function(a,b){return r.get(a,void 0,b,\"script\")}}),r.each([\"get\",\"post\"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,\"throws\":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not(\"body\").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&\"withCredentials\"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e[\"X-Requested-With\"]||(e[\"X-Requested-With\"]=\"XMLHttpRequest\");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,\"abort\"===a?h.abort():\"error\"===a?\"number\"!=typeof h.status?f(0,\"error\"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,\"text\"!==(h.responseType||\"text\")||\"string\"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c(\"error\"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c(\"abort\");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter(\"script\",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type=\"GET\")}),r.ajaxTransport(\"script\",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(\"<script>\").prop({charset:a.scriptCharset,src:a.url}).on(\"load error\",c=function(a){b.remove(),c=null,a&&f(\"error\"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Qb=[],Rb=/(=)\\?(?=&|$)|\\?\\?/;r.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var a=Qb.pop()||r.expando+\"_\"+rb++;return this[a]=!0,a}}),r.ajaxPrefilter(\"json jsonp\",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Rb.test(b.url)?\"url\":\"string\"==typeof b.data&&0===(b.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Rb.test(b.data)&&\"data\");if(h||\"jsonp\"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Rb,\"$1\"+e):b.jsonp!==!1&&(b.url+=(sb.test(b.url)?\"&\":\"?\")+b.jsonp+\"=\"+e),b.converters[\"script json\"]=function(){return g||r.error(e+\" was not called\"),g[0]},b.dataTypes[0]=\"json\",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Qb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),\"script\"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument(\"\").body;return a.innerHTML=\"<form></form><form></form>\",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if(\"string\"!=typeof a)return[];\"boolean\"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(\"\"),e=b.createElement(\"base\"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=B.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=oa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(\" \");return h>-1&&(d=r.trim(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&\"object\"==typeof b&&(e=\"POST\"),g.length>0&&r.ajax({url:a,type:e||\"GET\",dataType:\"html\",data:b}).done(function(a){f=arguments,g.html(d?r(\"<div>\").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length};function Sb(a){return r.isWindow(a)?a:9===a.nodeType&&a.defaultView}r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,\"position\"),l=r(a),m={};\"static\"===k&&(a.style.position=\"relative\"),h=l.offset(),f=r.css(a,\"top\"),i=r.css(a,\"left\"),j=(\"absolute\"===k||\"fixed\"===k)&&(f+i).indexOf(\"auto\")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),\"using\"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),d.width||d.height?(e=f.ownerDocument,c=Sb(e),b=e.documentElement,{top:d.top+c.pageYOffset-b.clientTop,left:d.left+c.pageXOffset-b.clientLeft}):d):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return\"fixed\"===r.css(c,\"position\")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),r.nodeName(a[0],\"html\")||(d=a.offset()),d={top:d.top+r.css(a[0],\"borderTopWidth\",!0),left:d.left+r.css(a[0],\"borderLeftWidth\",!0)}),{top:b.top-d.top-r.css(c,\"marginTop\",!0),left:b.left-d.left-r.css(c,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&\"static\"===r.css(a,\"position\"))a=a.offsetParent;return a||pa})}}),r.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(a,b){var c=\"pageYOffset\"===b;r.fn[a]=function(d){return S(this,function(a,d,e){var f=Sb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each([\"top\",\"left\"],function(a,b){r.cssHooks[b]=Na(o.pixelPosition,function(a,c){if(c)return c=Ma(a,b),Ka.test(c)?r(a).position()[b]+\"px\":c})}),r.each({Height:\"height\",Width:\"width\"},function(a,b){r.each({padding:\"inner\"+a,content:b,\"\":\"outer\"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||\"boolean\"!=typeof e),h=c||(e===!0||f===!0?\"margin\":\"border\");return S(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf(\"outer\")?b[\"inner\"+a]:b.document.documentElement[\"client\"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body[\"scroll\"+a],f[\"scroll\"+a],b.body[\"offset\"+a],f[\"offset\"+a],f[\"client\"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,\"**\"):this.off(b,a||\"**\",c)}}),r.parseJSON=JSON.parse,\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return r});var Tb=a.jQuery,Ub=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Ub),b&&a.jQuery===r&&(a.jQuery=Tb),r},b||(a.jQuery=a.$=r),r});\n"
  },
  {
    "path": "docs/sphinx/_build/_static/js/theme.js",
    "content": "require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({\"sphinx-rtd-theme\":[function(require,module,exports){\nvar jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');\n\n// Sphinx theme nav state\nfunction ThemeNav () {\n\n    var nav = {\n        navBar: null,\n        win: null,\n        winScroll: false,\n        winResize: false,\n        linkScroll: false,\n        winPosition: 0,\n        winHeight: null,\n        docHeight: null,\n        isRunning: false\n    };\n\n    nav.enable = function () {\n        var self = this;\n\n        if (!self.isRunning) {\n            self.isRunning = true;\n            jQuery(function ($) {\n                self.init($);\n\n                self.reset();\n                self.win.on('hashchange', self.reset);\n\n                // Set scroll monitor\n                self.win.on('scroll', function () {\n                    if (!self.linkScroll) {\n                        self.winScroll = true;\n                    }\n                });\n                setInterval(function () { if (self.winScroll) self.onScroll(); }, 25);\n\n                // Set resize monitor\n                self.win.on('resize', function () {\n                    self.winResize = true;\n                });\n                setInterval(function () { if (self.winResize) self.onResize(); }, 25);\n                self.onResize();\n            });\n        };\n    };\n\n    nav.init = function ($) {\n        var doc = $(document),\n            self = this;\n\n        this.navBar = $('div.wy-side-scroll:first');\n        this.win = $(window);\n\n        // Set up javascript UX bits\n        $(document)\n            // Shift nav in mobile when clicking the menu.\n            .on('click', \"[data-toggle='wy-nav-top']\", function() {\n                $(\"[data-toggle='wy-nav-shift']\").toggleClass(\"shift\");\n                $(\"[data-toggle='rst-versions']\").toggleClass(\"shift\");\n            })\n\n            // Nav menu link click operations\n            .on('click', \".wy-menu-vertical .current ul li a\", function() {\n                var target = $(this);\n                // Close menu when you click a link.\n                $(\"[data-toggle='wy-nav-shift']\").removeClass(\"shift\");\n                $(\"[data-toggle='rst-versions']\").toggleClass(\"shift\");\n                // Handle dynamic display of l3 and l4 nav lists\n                self.toggleCurrent(target);\n                self.hashChange();\n            })\n            .on('click', \"[data-toggle='rst-current-version']\", function() {\n                $(\"[data-toggle='rst-versions']\").toggleClass(\"shift-up\");\n            })\n\n        // Make tables responsive\n        $(\"table.docutils:not(.field-list)\")\n            .wrap(\"<div class='wy-table-responsive'></div>\");\n\n        // Add expand links to all parents of nested ul\n        $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {\n            var link = $(this);\n                expand = $('<span class=\"toctree-expand\"></span>');\n            expand.on('click', function (ev) {\n                self.toggleCurrent(link);\n                ev.stopPropagation();\n                return false;\n            });\n            link.prepend(expand);\n        });\n    };\n\n    nav.reset = function () {\n        // Get anchor from URL and open up nested nav\n        var anchor = encodeURI(window.location.hash);\n        if (anchor) {\n            try {\n                var link = $('.wy-menu-vertical')\n                    .find('[href=\"' + anchor + '\"]');\n                $('.wy-menu-vertical li.toctree-l1 li.current')\n                    .removeClass('current');\n                link.closest('li.toctree-l2').addClass('current');\n                link.closest('li.toctree-l3').addClass('current');\n                link.closest('li.toctree-l4').addClass('current');\n            }\n            catch (err) {\n                console.log(\"Error expanding nav for anchor\", err);\n            }\n        }\n    };\n\n    nav.onScroll = function () {\n        this.winScroll = false;\n        var newWinPosition = this.win.scrollTop(),\n            winBottom = newWinPosition + this.winHeight,\n            navPosition = this.navBar.scrollTop(),\n            newNavPosition = navPosition + (newWinPosition - this.winPosition);\n        if (newWinPosition < 0 || winBottom > this.docHeight) {\n            return;\n        }\n        this.navBar.scrollTop(newNavPosition);\n        this.winPosition = newWinPosition;\n    };\n\n    nav.onResize = function () {\n        this.winResize = false;\n        this.winHeight = this.win.height();\n        this.docHeight = $(document).height();\n    };\n\n    nav.hashChange = function () {\n        this.linkScroll = true;\n        this.win.one('hashchange', function () {\n            this.linkScroll = false;\n        });\n    };\n\n    nav.toggleCurrent = function (elem) {\n        var parent_li = elem.closest('li');\n        parent_li.siblings('li.current').removeClass('current');\n        parent_li.siblings().find('li.current').removeClass('current');\n        parent_li.find('> ul li.current').removeClass('current');\n        parent_li.toggleClass('current');\n    }\n\n    return nav;\n};\n\nmodule.exports.ThemeNav = ThemeNav();\n\nif (typeof(window) != 'undefined') {\n    window.SphinxRtdTheme = { StickyNav: module.exports.ThemeNav };\n}\n\n},{\"jquery\":\"jquery\"}]},{},[\"sphinx-rtd-theme\"]);\n"
  },
  {
    "path": "docs/sphinx/_build/_static/language_data.js",
    "content": "/*\n * language_data.js\n * ~~~~~~~~~~~~~~~~\n *\n * This script contains the language-specific data used by searchtools.js,\n * namely the list of stopwords, stemmer, scorer and splitter.\n *\n * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\nvar stopwords = [\"a\", \"and\", \"are\", \"as\", \"at\", \"be\", \"but\", \"by\", \"for\", \"if\", \"in\", \"into\", \"is\", \"it\", \"near\", \"no\", \"not\", \"of\", \"on\", \"or\", \"such\", \"that\", \"the\", \"their\", \"then\", \"there\", \"these\", \"they\", \"this\", \"to\", \"was\", \"will\", \"with\"];\n\n\n/* Non-minified version is copied as a separate JS file, is available */\n\n/**\n * Porter Stemmer\n */\nvar Stemmer = function() {\n\n  var step2list = {\n    ational: 'ate',\n    tional: 'tion',\n    enci: 'ence',\n    anci: 'ance',\n    izer: 'ize',\n    bli: 'ble',\n    alli: 'al',\n    entli: 'ent',\n    eli: 'e',\n    ousli: 'ous',\n    ization: 'ize',\n    ation: 'ate',\n    ator: 'ate',\n    alism: 'al',\n    iveness: 'ive',\n    fulness: 'ful',\n    ousness: 'ous',\n    aliti: 'al',\n    iviti: 'ive',\n    biliti: 'ble',\n    logi: 'log'\n  };\n\n  var step3list = {\n    icate: 'ic',\n    ative: '',\n    alize: 'al',\n    iciti: 'ic',\n    ical: 'ic',\n    ful: '',\n    ness: ''\n  };\n\n  var c = \"[^aeiou]\";          // consonant\n  var v = \"[aeiouy]\";          // vowel\n  var C = c + \"[^aeiouy]*\";    // consonant sequence\n  var V = v + \"[aeiou]*\";      // vowel sequence\n\n  var mgr0 = \"^(\" + C + \")?\" + V + C;                      // [C]VC... is m>0\n  var meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\";    // [C]VC[V] is m=1\n  var mgr1 = \"^(\" + C + \")?\" + V + C + V + C;              // [C]VCVC... is m>1\n  var s_v   = \"^(\" + C + \")?\" + v;                         // vowel in stem\n\n  this.stemWord = function (w) {\n    var stem;\n    var suffix;\n    var firstch;\n    var origword = w;\n\n    if (w.length < 3)\n      return w;\n\n    var re;\n    var re2;\n    var re3;\n    var re4;\n\n    firstch = w.substr(0,1);\n    if (firstch == \"y\")\n      w = firstch.toUpperCase() + w.substr(1);\n\n    // Step 1a\n    re = /^(.+?)(ss|i)es$/;\n    re2 = /^(.+?)([^s])s$/;\n\n    if (re.test(w))\n      w = w.replace(re,\"$1$2\");\n    else if (re2.test(w))\n      w = w.replace(re2,\"$1$2\");\n\n    // Step 1b\n    re = /^(.+?)eed$/;\n    re2 = /^(.+?)(ed|ing)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      re = new RegExp(mgr0);\n      if (re.test(fp[1])) {\n        re = /.$/;\n        w = w.replace(re,\"\");\n      }\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1];\n      re2 = new RegExp(s_v);\n      if (re2.test(stem)) {\n        w = stem;\n        re2 = /(at|bl|iz)$/;\n        re3 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n        re4 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n        if (re2.test(w))\n          w = w + \"e\";\n        else if (re3.test(w)) {\n          re = /.$/;\n          w = w.replace(re,\"\");\n        }\n        else if (re4.test(w))\n          w = w + \"e\";\n      }\n    }\n\n    // Step 1c\n    re = /^(.+?)y$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(s_v);\n      if (re.test(stem))\n        w = stem + \"i\";\n    }\n\n    // Step 2\n    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step2list[suffix];\n    }\n\n    // Step 3\n    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step3list[suffix];\n    }\n\n    // Step 4\n    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n    re2 = /^(.+?)(s|t)(ion)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      if (re.test(stem))\n        w = stem;\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1] + fp[2];\n      re2 = new RegExp(mgr1);\n      if (re2.test(stem))\n        w = stem;\n    }\n\n    // Step 5\n    re = /^(.+?)e$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      re2 = new RegExp(meq1);\n      re3 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))\n        w = stem;\n    }\n    re = /ll$/;\n    re2 = new RegExp(mgr1);\n    if (re.test(w) && re2.test(w)) {\n      re = /.$/;\n      w = w.replace(re,\"\");\n    }\n\n    // and turn initial Y back to y\n    if (firstch == \"y\")\n      w = firstch.toLowerCase() + w.substr(1);\n    return w;\n  }\n}\n\n"
  },
  {
    "path": "docs/sphinx/_build/_static/pygments.css",
    "content": "pre { line-height: 125%; margin: 0; }\ntd.linenos pre { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; }\ntd.linenos pre.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.highlight .hll { background-color: #ffffcc }\n.highlight { background: #eeffcc; }\n.highlight .c { color: #408090; font-style: italic } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { color: #007020; font-weight: bold } /* Keyword */\n.highlight .o { color: #666666 } /* Operator */\n.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */\n.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #007020 } /* Comment.Preproc */\n.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */\n.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #333333 } /* Generic.Output */\n.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0044DD } /* Generic.Traceback */\n.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #007020 } /* Keyword.Pseudo */\n.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #902000 } /* Keyword.Type */\n.highlight .m { color: #208050 } /* Literal.Number */\n.highlight .s { color: #4070a0 } /* Literal.String */\n.highlight .na { color: #4070a0 } /* Name.Attribute */\n.highlight .nb { color: #007020 } /* Name.Builtin */\n.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */\n.highlight .no { color: #60add5 } /* Name.Constant */\n.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */\n.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #007020 } /* Name.Exception */\n.highlight .nf { color: #06287e } /* Name.Function */\n.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */\n.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #bb60d5 } /* Name.Variable */\n.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mb { color: #208050 } /* Literal.Number.Bin */\n.highlight .mf { color: #208050 } /* Literal.Number.Float */\n.highlight .mh { color: #208050 } /* Literal.Number.Hex */\n.highlight .mi { color: #208050 } /* Literal.Number.Integer */\n.highlight .mo { color: #208050 } /* Literal.Number.Oct */\n.highlight .sa { color: #4070a0 } /* Literal.String.Affix */\n.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */\n.highlight .sc { color: #4070a0 } /* Literal.String.Char */\n.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */\n.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #4070a0 } /* Literal.String.Double */\n.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */\n.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */\n.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */\n.highlight .sx { color: #c65d09 } /* Literal.String.Other */\n.highlight .sr { color: #235388 } /* Literal.String.Regex */\n.highlight .s1 { color: #4070a0 } /* Literal.String.Single */\n.highlight .ss { color: #517918 } /* Literal.String.Symbol */\n.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */\n.highlight .fm { color: #06287e } /* Name.Function.Magic */\n.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */\n.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */\n.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */\n.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */\n.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */"
  },
  {
    "path": "docs/sphinx/_build/_static/searchtools.js",
    "content": "/*\n * searchtools.js_t\n * ~~~~~~~~~~~~~~~~\n *\n * Sphinx JavaScript utilities for the full-text search.\n *\n * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n\n/* Non-minified version JS is _stemmer.js if file is provided */ \n/**\n * Porter Stemmer\n */\nvar Stemmer = function() {\n\n  var step2list = {\n    ational: 'ate',\n    tional: 'tion',\n    enci: 'ence',\n    anci: 'ance',\n    izer: 'ize',\n    bli: 'ble',\n    alli: 'al',\n    entli: 'ent',\n    eli: 'e',\n    ousli: 'ous',\n    ization: 'ize',\n    ation: 'ate',\n    ator: 'ate',\n    alism: 'al',\n    iveness: 'ive',\n    fulness: 'ful',\n    ousness: 'ous',\n    aliti: 'al',\n    iviti: 'ive',\n    biliti: 'ble',\n    logi: 'log'\n  };\n\n  var step3list = {\n    icate: 'ic',\n    ative: '',\n    alize: 'al',\n    iciti: 'ic',\n    ical: 'ic',\n    ful: '',\n    ness: ''\n  };\n\n  var c = \"[^aeiou]\";          // consonant\n  var v = \"[aeiouy]\";          // vowel\n  var C = c + \"[^aeiouy]*\";    // consonant sequence\n  var V = v + \"[aeiou]*\";      // vowel sequence\n\n  var mgr0 = \"^(\" + C + \")?\" + V + C;                      // [C]VC... is m>0\n  var meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\";    // [C]VC[V] is m=1\n  var mgr1 = \"^(\" + C + \")?\" + V + C + V + C;              // [C]VCVC... is m>1\n  var s_v   = \"^(\" + C + \")?\" + v;                         // vowel in stem\n\n  this.stemWord = function (w) {\n    var stem;\n    var suffix;\n    var firstch;\n    var origword = w;\n\n    if (w.length < 3)\n      return w;\n\n    var re;\n    var re2;\n    var re3;\n    var re4;\n\n    firstch = w.substr(0,1);\n    if (firstch == \"y\")\n      w = firstch.toUpperCase() + w.substr(1);\n\n    // Step 1a\n    re = /^(.+?)(ss|i)es$/;\n    re2 = /^(.+?)([^s])s$/;\n\n    if (re.test(w))\n      w = w.replace(re,\"$1$2\");\n    else if (re2.test(w))\n      w = w.replace(re2,\"$1$2\");\n\n    // Step 1b\n    re = /^(.+?)eed$/;\n    re2 = /^(.+?)(ed|ing)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      re = new RegExp(mgr0);\n      if (re.test(fp[1])) {\n        re = /.$/;\n        w = w.replace(re,\"\");\n      }\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1];\n      re2 = new RegExp(s_v);\n      if (re2.test(stem)) {\n        w = stem;\n        re2 = /(at|bl|iz)$/;\n        re3 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n        re4 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n        if (re2.test(w))\n          w = w + \"e\";\n        else if (re3.test(w)) {\n          re = /.$/;\n          w = w.replace(re,\"\");\n        }\n        else if (re4.test(w))\n          w = w + \"e\";\n      }\n    }\n\n    // Step 1c\n    re = /^(.+?)y$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(s_v);\n      if (re.test(stem))\n        w = stem + \"i\";\n    }\n\n    // Step 2\n    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step2list[suffix];\n    }\n\n    // Step 3\n    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step3list[suffix];\n    }\n\n    // Step 4\n    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n    re2 = /^(.+?)(s|t)(ion)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      if (re.test(stem))\n        w = stem;\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1] + fp[2];\n      re2 = new RegExp(mgr1);\n      if (re2.test(stem))\n        w = stem;\n    }\n\n    // Step 5\n    re = /^(.+?)e$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      re2 = new RegExp(meq1);\n      re3 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))\n        w = stem;\n    }\n    re = /ll$/;\n    re2 = new RegExp(mgr1);\n    if (re.test(w) && re2.test(w)) {\n      re = /.$/;\n      w = w.replace(re,\"\");\n    }\n\n    // and turn initial Y back to y\n    if (firstch == \"y\")\n      w = firstch.toLowerCase() + w.substr(1);\n    return w;\n  }\n}\n\n\n\n/**\n * Simple result scoring code.\n */\nvar Scorer = {\n  // Implement the following function to further tweak the score for each result\n  // The function takes a result array [filename, title, anchor, descr, score]\n  // and returns the new score.\n  /*\n  score: function(result) {\n    return result[4];\n  },\n  */\n\n  // query matches the full name of an object\n  objNameMatch: 11,\n  // or matches in the last dotted part of the object name\n  objPartialMatch: 6,\n  // Additive scores depending on the priority of the object\n  objPrio: {0:  15,   // used to be importantResults\n            1:  5,   // used to be objectResults\n            2: -5},  // used to be unimportantResults\n  //  Used when the priority is not in the mapping.\n  objPrioDefault: 0,\n\n  // query found in title\n  title: 15,\n  // query found in terms\n  term: 5\n};\n\n\n\n\n\nvar splitChars = (function() {\n    var result = {};\n    var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,\n         1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,\n         2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,\n         2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,\n         3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,\n         3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,\n         4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,\n         8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,\n         11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,\n         43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];\n    var i, j, start, end;\n    for (i = 0; i < singles.length; i++) {\n        result[singles[i]] = true;\n    }\n    var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],\n         [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],\n         [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],\n         [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],\n         [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],\n         [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],\n         [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],\n         [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],\n         [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],\n         [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],\n         [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],\n         [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],\n         [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],\n         [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],\n         [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],\n         [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],\n         [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],\n         [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],\n         [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],\n         [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],\n         [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],\n         [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],\n         [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],\n         [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],\n         [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],\n         [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],\n         [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],\n         [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],\n         [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],\n         [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],\n         [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],\n         [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],\n         [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],\n         [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],\n         [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],\n         [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],\n         [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],\n         [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],\n         [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],\n         [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],\n         [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],\n         [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],\n         [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],\n         [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],\n         [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],\n         [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],\n         [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],\n         [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],\n         [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];\n    for (i = 0; i < ranges.length; i++) {\n        start = ranges[i][0];\n        end = ranges[i][1];\n        for (j = start; j <= end; j++) {\n            result[j] = true;\n        }\n    }\n    return result;\n})();\n\nfunction splitQuery(query) {\n    var result = [];\n    var start = -1;\n    for (var i = 0; i < query.length; i++) {\n        if (splitChars[query.charCodeAt(i)]) {\n            if (start !== -1) {\n                result.push(query.slice(start, i));\n                start = -1;\n            }\n        } else if (start === -1) {\n            start = i;\n        }\n    }\n    if (start !== -1) {\n        result.push(query.slice(start));\n    }\n    return result;\n}\n\n\n\n\n/**\n * Search Module\n */\nvar Search = {\n\n  _index : null,\n  _queued_query : null,\n  _pulse_status : -1,\n\n  init : function() {\n      var params = $.getQueryParameters();\n      if (params.q) {\n          var query = params.q[0];\n          $('input[name=\"q\"]')[0].value = query;\n          this.performSearch(query);\n      }\n  },\n\n  loadIndex : function(url) {\n    $.ajax({type: \"GET\", url: url, data: null,\n            dataType: \"script\", cache: true,\n            complete: function(jqxhr, textstatus) {\n              if (textstatus != \"success\") {\n                document.getElementById(\"searchindexloader\").src = url;\n              }\n            }});\n  },\n\n  setIndex : function(index) {\n    var q;\n    this._index = index;\n    if ((q = this._queued_query) !== null) {\n      this._queued_query = null;\n      Search.query(q);\n    }\n  },\n\n  hasIndex : function() {\n      return this._index !== null;\n  },\n\n  deferQuery : function(query) {\n      this._queued_query = query;\n  },\n\n  stopPulse : function() {\n      this._pulse_status = 0;\n  },\n\n  startPulse : function() {\n    if (this._pulse_status >= 0)\n        return;\n    function pulse() {\n      var i;\n      Search._pulse_status = (Search._pulse_status + 1) % 4;\n      var dotString = '';\n      for (i = 0; i < Search._pulse_status; i++)\n        dotString += '.';\n      Search.dots.text(dotString);\n      if (Search._pulse_status > -1)\n        window.setTimeout(pulse, 500);\n    }\n    pulse();\n  },\n\n  /**\n   * perform a search for something (or wait until index is loaded)\n   */\n  performSearch : function(query) {\n    // create the required interface elements\n    this.out = $('#search-results');\n    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);\n    this.dots = $('<span></span>').appendTo(this.title);\n    this.status = $('<p style=\"display: none\"></p>').appendTo(this.out);\n    this.output = $('<ul class=\"search\"/>').appendTo(this.out);\n\n    $('#search-progress').text(_('Preparing search...'));\n    this.startPulse();\n\n    // index already loaded, the browser was quick!\n    if (this.hasIndex())\n      this.query(query);\n    else\n      this.deferQuery(query);\n  },\n\n  /**\n   * execute search (requires search index to be loaded)\n   */\n  query : function(query) {\n    var i;\n    var stopwords = [\"a\",\"and\",\"are\",\"as\",\"at\",\"be\",\"but\",\"by\",\"for\",\"if\",\"in\",\"into\",\"is\",\"it\",\"near\",\"no\",\"not\",\"of\",\"on\",\"or\",\"such\",\"that\",\"the\",\"their\",\"then\",\"there\",\"these\",\"they\",\"this\",\"to\",\"was\",\"will\",\"with\"];\n\n    // stem the searchterms and add them to the correct list\n    var stemmer = new Stemmer();\n    var searchterms = [];\n    var excluded = [];\n    var hlterms = [];\n    var tmp = splitQuery(query);\n    var objectterms = [];\n    for (i = 0; i < tmp.length; i++) {\n      if (tmp[i] !== \"\") {\n          objectterms.push(tmp[i].toLowerCase());\n      }\n\n      if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\\d+$/) ||\n          tmp[i] === \"\") {\n        // skip this \"word\"\n        continue;\n      }\n      // stem the word\n      var word = stemmer.stemWord(tmp[i].toLowerCase());\n      // prevent stemmer from cutting word smaller than two chars\n      if(word.length < 3 && tmp[i].length >= 3) {\n        word = tmp[i];\n      }\n      var toAppend;\n      // select the correct list\n      if (word[0] == '-') {\n        toAppend = excluded;\n        word = word.substr(1);\n      }\n      else {\n        toAppend = searchterms;\n        hlterms.push(tmp[i].toLowerCase());\n      }\n      // only add if not already in the list\n      if (!$u.contains(toAppend, word))\n        toAppend.push(word);\n    }\n    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(\" \"));\n\n    // console.debug('SEARCH: searching for:');\n    // console.info('required: ', searchterms);\n    // console.info('excluded: ', excluded);\n\n    // prepare search\n    var terms = this._index.terms;\n    var titleterms = this._index.titleterms;\n\n    // array of [filename, title, anchor, descr, score]\n    var results = [];\n    $('#search-progress').empty();\n\n    // lookup as object\n    for (i = 0; i < objectterms.length; i++) {\n      var others = [].concat(objectterms.slice(0, i),\n                             objectterms.slice(i+1, objectterms.length));\n      results = results.concat(this.performObjectSearch(objectterms[i], others));\n    }\n\n    // lookup as search terms in fulltext\n    results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));\n\n    // let the scorer override scores with a custom scoring function\n    if (Scorer.score) {\n      for (i = 0; i < results.length; i++)\n        results[i][4] = Scorer.score(results[i]);\n    }\n\n    // now sort the results by score (in opposite order of appearance, since the\n    // display function below uses pop() to retrieve items) and then\n    // alphabetically\n    results.sort(function(a, b) {\n      var left = a[4];\n      var right = b[4];\n      if (left > right) {\n        return 1;\n      } else if (left < right) {\n        return -1;\n      } else {\n        // same score: sort alphabetically\n        left = a[1].toLowerCase();\n        right = b[1].toLowerCase();\n        return (left > right) ? -1 : ((left < right) ? 1 : 0);\n      }\n    });\n\n    // for debugging\n    //Search.lastresults = results.slice();  // a copy\n    //console.info('search results:', Search.lastresults);\n\n    // print the results\n    var resultCount = results.length;\n    function displayNextItem() {\n      // results left, load the summary and display it\n      if (results.length) {\n        var item = results.pop();\n        var listItem = $('<li style=\"display:none\"></li>');\n        if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {\n          // dirhtml builder\n          var dirname = item[0] + '/';\n          if (dirname.match(/\\/index\\/$/)) {\n            dirname = dirname.substring(0, dirname.length-6);\n          } else if (dirname == 'index/') {\n            dirname = '';\n          }\n          listItem.append($('<a/>').attr('href',\n            DOCUMENTATION_OPTIONS.URL_ROOT + dirname +\n            highlightstring + item[2]).html(item[1]));\n        } else {\n          // normal html builders\n          listItem.append($('<a/>').attr('href',\n            item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +\n            highlightstring + item[2]).html(item[1]));\n        }\n        if (item[3]) {\n          listItem.append($('<span> (' + item[3] + ')</span>'));\n          Search.output.append(listItem);\n          listItem.slideDown(5, function() {\n            displayNextItem();\n          });\n        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {\n          var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;\n          $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),\n                  dataType: \"text\",\n                  complete: function(jqxhr, textstatus) {\n                    var data = jqxhr.responseText;\n                    if (data !== '' && data !== undefined) {\n                      listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));\n                    }\n                    Search.output.append(listItem);\n                    listItem.slideDown(5, function() {\n                      displayNextItem();\n                    });\n                  }});\n        } else {\n          // no source available, just display title\n          Search.output.append(listItem);\n          listItem.slideDown(5, function() {\n            displayNextItem();\n          });\n        }\n      }\n      // search finished, update title and status message\n      else {\n        Search.stopPulse();\n        Search.title.text(_('Search Results'));\n        if (!resultCount)\n          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\\'ve selected enough categories.'));\n        else\n            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));\n        Search.status.fadeIn(500);\n      }\n    }\n    displayNextItem();\n  },\n\n  /**\n   * search for object names\n   */\n  performObjectSearch : function(object, otherterms) {\n    var filenames = this._index.filenames;\n    var docnames = this._index.docnames;\n    var objects = this._index.objects;\n    var objnames = this._index.objnames;\n    var titles = this._index.titles;\n\n    var i;\n    var results = [];\n\n    for (var prefix in objects) {\n      for (var name in objects[prefix]) {\n        var fullname = (prefix ? prefix + '.' : '') + name;\n        if (fullname.toLowerCase().indexOf(object) > -1) {\n          var score = 0;\n          var parts = fullname.split('.');\n          // check for different match types: exact matches of full name or\n          // \"last name\" (i.e. last dotted part)\n          if (fullname == object || parts[parts.length - 1] == object) {\n            score += Scorer.objNameMatch;\n          // matches in last name\n          } else if (parts[parts.length - 1].indexOf(object) > -1) {\n            score += Scorer.objPartialMatch;\n          }\n          var match = objects[prefix][name];\n          var objname = objnames[match[1]][2];\n          var title = titles[match[0]];\n          // If more than one term searched for, we require other words to be\n          // found in the name/title/description\n          if (otherterms.length > 0) {\n            var haystack = (prefix + ' ' + name + ' ' +\n                            objname + ' ' + title).toLowerCase();\n            var allfound = true;\n            for (i = 0; i < otherterms.length; i++) {\n              if (haystack.indexOf(otherterms[i]) == -1) {\n                allfound = false;\n                break;\n              }\n            }\n            if (!allfound) {\n              continue;\n            }\n          }\n          var descr = objname + _(', in ') + title;\n\n          var anchor = match[3];\n          if (anchor === '')\n            anchor = fullname;\n          else if (anchor == '-')\n            anchor = objnames[match[1]][1] + '-' + fullname;\n          // add custom score for some objects according to scorer\n          if (Scorer.objPrio.hasOwnProperty(match[2])) {\n            score += Scorer.objPrio[match[2]];\n          } else {\n            score += Scorer.objPrioDefault;\n          }\n          results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);\n        }\n      }\n    }\n\n    return results;\n  },\n\n  /**\n   * search for full-text terms in the index\n   */\n  performTermsSearch : function(searchterms, excluded, terms, titleterms) {\n    var docnames = this._index.docnames;\n    var filenames = this._index.filenames;\n    var titles = this._index.titles;\n\n    var i, j, file;\n    var fileMap = {};\n    var scoreMap = {};\n    var results = [];\n\n    // perform the search on the required terms\n    for (i = 0; i < searchterms.length; i++) {\n      var word = searchterms[i];\n      var files = [];\n      var _o = [\n        {files: terms[word], score: Scorer.term},\n        {files: titleterms[word], score: Scorer.title}\n      ];\n\n      // no match but word was a required one\n      if ($u.every(_o, function(o){return o.files === undefined;})) {\n        break;\n      }\n      // found search word in contents\n      $u.each(_o, function(o) {\n        var _files = o.files;\n        if (_files === undefined)\n          return\n\n        if (_files.length === undefined)\n          _files = [_files];\n        files = files.concat(_files);\n\n        // set score for the word in each file to Scorer.term\n        for (j = 0; j < _files.length; j++) {\n          file = _files[j];\n          if (!(file in scoreMap))\n            scoreMap[file] = {}\n          scoreMap[file][word] = o.score;\n        }\n      });\n\n      // create the mapping\n      for (j = 0; j < files.length; j++) {\n        file = files[j];\n        if (file in fileMap)\n          fileMap[file].push(word);\n        else\n          fileMap[file] = [word];\n      }\n    }\n\n    // now check if the files don't contain excluded terms\n    for (file in fileMap) {\n      var valid = true;\n\n      // check if all requirements are matched\n      if (fileMap[file].length != searchterms.length)\n          continue;\n\n      // ensure that none of the excluded terms is in the search result\n      for (i = 0; i < excluded.length; i++) {\n        if (terms[excluded[i]] == file ||\n            titleterms[excluded[i]] == file ||\n            $u.contains(terms[excluded[i]] || [], file) ||\n            $u.contains(titleterms[excluded[i]] || [], file)) {\n          valid = false;\n          break;\n        }\n      }\n\n      // if we have still a valid result we can add it to the result list\n      if (valid) {\n        // select one (max) score for the file.\n        // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...\n        var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));\n        results.push([docnames[file], titles[file], '', null, score, filenames[file]]);\n      }\n    }\n    return results;\n  },\n\n  /**\n   * helper function to return a node containing the\n   * search summary for a given text. keywords is a list\n   * of stemmed words, hlwords is the list of normal, unstemmed\n   * words. the first one is used to find the occurrence, the\n   * latter for highlighting it.\n   */\n  makeSearchSummary : function(text, keywords, hlwords) {\n    var textLower = text.toLowerCase();\n    var start = 0;\n    $.each(keywords, function() {\n      var i = textLower.indexOf(this.toLowerCase());\n      if (i > -1)\n        start = i;\n    });\n    start = Math.max(start - 120, 0);\n    var excerpt = ((start > 0) ? '...' : '') +\n      $.trim(text.substr(start, 240)) +\n      ((start + 240 - text.length) ? '...' : '');\n    var rv = $('<div class=\"context\"></div>').text(excerpt);\n    $.each(hlwords, function() {\n      rv = rv.highlightText(this, 'highlighted');\n    });\n    return rv;\n  }\n};\n\n$(document).ready(function() {\n  Search.init();\n});"
  },
  {
    "path": "docs/sphinx/_build/_static/underscore-1.13.1.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define('underscore', factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () {\n    var current = global._;\n    var exports = global._ = factory();\n    exports.noConflict = function () { global._ = current; return exports; };\n  }()));\n}(this, (function () {\n  //     Underscore.js 1.13.1\n  //     https://underscorejs.org\n  //     (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors\n  //     Underscore may be freely distributed under the MIT license.\n\n  // Current version.\n  var VERSION = '1.13.1';\n\n  // Establish the root object, `window` (`self`) in the browser, `global`\n  // on the server, or `this` in some virtual machines. We use `self`\n  // instead of `window` for `WebWorker` support.\n  var root = typeof self == 'object' && self.self === self && self ||\n            typeof global == 'object' && global.global === global && global ||\n            Function('return this')() ||\n            {};\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype;\n  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var push = ArrayProto.push,\n      slice = ArrayProto.slice,\n      toString = ObjProto.toString,\n      hasOwnProperty = ObjProto.hasOwnProperty;\n\n  // Modern feature detection.\n  var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',\n      supportsDataView = typeof DataView !== 'undefined';\n\n  // All **ECMAScript 5+** native function implementations that we hope to use\n  // are declared here.\n  var nativeIsArray = Array.isArray,\n      nativeKeys = Object.keys,\n      nativeCreate = Object.create,\n      nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;\n\n  // Create references to these builtin functions because we override them.\n  var _isNaN = isNaN,\n      _isFinite = isFinite;\n\n  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\n  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');\n  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',\n    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];\n\n  // The largest integer that can be represented exactly.\n  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;\n\n  // Some functions take a variable number of arguments, or a few expected\n  // arguments at the beginning and then a variable number of values to operate\n  // on. This helper accumulates all remaining arguments past the function’s\n  // argument length (or an explicit `startIndex`), into an array that becomes\n  // the last argument. Similar to ES6’s \"rest parameter\".\n  function restArguments(func, startIndex) {\n    startIndex = startIndex == null ? func.length - 1 : +startIndex;\n    return function() {\n      var length = Math.max(arguments.length - startIndex, 0),\n          rest = Array(length),\n          index = 0;\n      for (; index < length; index++) {\n        rest[index] = arguments[index + startIndex];\n      }\n      switch (startIndex) {\n        case 0: return func.call(this, rest);\n        case 1: return func.call(this, arguments[0], rest);\n        case 2: return func.call(this, arguments[0], arguments[1], rest);\n      }\n      var args = Array(startIndex + 1);\n      for (index = 0; index < startIndex; index++) {\n        args[index] = arguments[index];\n      }\n      args[startIndex] = rest;\n      return func.apply(this, args);\n    };\n  }\n\n  // Is a given variable an object?\n  function isObject(obj) {\n    var type = typeof obj;\n    return type === 'function' || type === 'object' && !!obj;\n  }\n\n  // Is a given value equal to null?\n  function isNull(obj) {\n    return obj === null;\n  }\n\n  // Is a given variable undefined?\n  function isUndefined(obj) {\n    return obj === void 0;\n  }\n\n  // Is a given value a boolean?\n  function isBoolean(obj) {\n    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';\n  }\n\n  // Is a given value a DOM element?\n  function isElement(obj) {\n    return !!(obj && obj.nodeType === 1);\n  }\n\n  // Internal function for creating a `toString`-based type tester.\n  function tagTester(name) {\n    var tag = '[object ' + name + ']';\n    return function(obj) {\n      return toString.call(obj) === tag;\n    };\n  }\n\n  var isString = tagTester('String');\n\n  var isNumber = tagTester('Number');\n\n  var isDate = tagTester('Date');\n\n  var isRegExp = tagTester('RegExp');\n\n  var isError = tagTester('Error');\n\n  var isSymbol = tagTester('Symbol');\n\n  var isArrayBuffer = tagTester('ArrayBuffer');\n\n  var isFunction = tagTester('Function');\n\n  // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old\n  // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).\n  var nodelist = root.document && root.document.childNodes;\n  if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {\n    isFunction = function(obj) {\n      return typeof obj == 'function' || false;\n    };\n  }\n\n  var isFunction$1 = isFunction;\n\n  var hasObjectTag = tagTester('Object');\n\n  // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.\n  // In IE 11, the most common among them, this problem also applies to\n  // `Map`, `WeakMap` and `Set`.\n  var hasStringTagBug = (\n        supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))\n      ),\n      isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));\n\n  var isDataView = tagTester('DataView');\n\n  // In IE 10 - Edge 13, we need a different heuristic\n  // to determine whether an object is a `DataView`.\n  function ie10IsDataView(obj) {\n    return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);\n  }\n\n  var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView);\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native `Array.isArray`.\n  var isArray = nativeIsArray || tagTester('Array');\n\n  // Internal function to check whether `key` is an own property name of `obj`.\n  function has$1(obj, key) {\n    return obj != null && hasOwnProperty.call(obj, key);\n  }\n\n  var isArguments = tagTester('Arguments');\n\n  // Define a fallback version of the method in browsers (ahem, IE < 9), where\n  // there isn't any inspectable \"Arguments\" type.\n  (function() {\n    if (!isArguments(arguments)) {\n      isArguments = function(obj) {\n        return has$1(obj, 'callee');\n      };\n    }\n  }());\n\n  var isArguments$1 = isArguments;\n\n  // Is a given object a finite number?\n  function isFinite$1(obj) {\n    return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));\n  }\n\n  // Is the given value `NaN`?\n  function isNaN$1(obj) {\n    return isNumber(obj) && _isNaN(obj);\n  }\n\n  // Predicate-generating function. Often useful outside of Underscore.\n  function constant(value) {\n    return function() {\n      return value;\n    };\n  }\n\n  // Common internal logic for `isArrayLike` and `isBufferLike`.\n  function createSizePropertyCheck(getSizeProperty) {\n    return function(collection) {\n      var sizeProperty = getSizeProperty(collection);\n      return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;\n    }\n  }\n\n  // Internal helper to generate a function to obtain property `key` from `obj`.\n  function shallowProperty(key) {\n    return function(obj) {\n      return obj == null ? void 0 : obj[key];\n    };\n  }\n\n  // Internal helper to obtain the `byteLength` property of an object.\n  var getByteLength = shallowProperty('byteLength');\n\n  // Internal helper to determine whether we should spend extensive checks against\n  // `ArrayBuffer` et al.\n  var isBufferLike = createSizePropertyCheck(getByteLength);\n\n  // Is a given value a typed array?\n  var typedArrayPattern = /\\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\\]/;\n  function isTypedArray(obj) {\n    // `ArrayBuffer.isView` is the most future-proof, so use it when available.\n    // Otherwise, fall back on the above regular expression.\n    return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) :\n                  isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));\n  }\n\n  var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false);\n\n  // Internal helper to obtain the `length` property of an object.\n  var getLength = shallowProperty('length');\n\n  // Internal helper to create a simple lookup structure.\n  // `collectNonEnumProps` used to depend on `_.contains`, but this led to\n  // circular imports. `emulatedSet` is a one-off solution that only works for\n  // arrays of strings.\n  function emulatedSet(keys) {\n    var hash = {};\n    for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;\n    return {\n      contains: function(key) { return hash[key]; },\n      push: function(key) {\n        hash[key] = true;\n        return keys.push(key);\n      }\n    };\n  }\n\n  // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't\n  // be iterated by `for key in ...` and thus missed. Extends `keys` in place if\n  // needed.\n  function collectNonEnumProps(obj, keys) {\n    keys = emulatedSet(keys);\n    var nonEnumIdx = nonEnumerableProps.length;\n    var constructor = obj.constructor;\n    var proto = isFunction$1(constructor) && constructor.prototype || ObjProto;\n\n    // Constructor is a special case.\n    var prop = 'constructor';\n    if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop);\n\n    while (nonEnumIdx--) {\n      prop = nonEnumerableProps[nonEnumIdx];\n      if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {\n        keys.push(prop);\n      }\n    }\n  }\n\n  // Retrieve the names of an object's own properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`.\n  function keys(obj) {\n    if (!isObject(obj)) return [];\n    if (nativeKeys) return nativeKeys(obj);\n    var keys = [];\n    for (var key in obj) if (has$1(obj, key)) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  }\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  function isEmpty(obj) {\n    if (obj == null) return true;\n    // Skip the more expensive `toString`-based type checks if `obj` has no\n    // `.length`.\n    var length = getLength(obj);\n    if (typeof length == 'number' && (\n      isArray(obj) || isString(obj) || isArguments$1(obj)\n    )) return length === 0;\n    return getLength(keys(obj)) === 0;\n  }\n\n  // Returns whether an object has a given set of `key:value` pairs.\n  function isMatch(object, attrs) {\n    var _keys = keys(attrs), length = _keys.length;\n    if (object == null) return !length;\n    var obj = Object(object);\n    for (var i = 0; i < length; i++) {\n      var key = _keys[i];\n      if (attrs[key] !== obj[key] || !(key in obj)) return false;\n    }\n    return true;\n  }\n\n  // If Underscore is called as a function, it returns a wrapped object that can\n  // be used OO-style. This wrapper holds altered versions of all functions added\n  // through `_.mixin`. Wrapped objects may be chained.\n  function _$1(obj) {\n    if (obj instanceof _$1) return obj;\n    if (!(this instanceof _$1)) return new _$1(obj);\n    this._wrapped = obj;\n  }\n\n  _$1.VERSION = VERSION;\n\n  // Extracts the result from a wrapped and chained object.\n  _$1.prototype.value = function() {\n    return this._wrapped;\n  };\n\n  // Provide unwrapping proxies for some methods used in engine operations\n  // such as arithmetic and JSON stringification.\n  _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value;\n\n  _$1.prototype.toString = function() {\n    return String(this._wrapped);\n  };\n\n  // Internal function to wrap or shallow-copy an ArrayBuffer,\n  // typed array or DataView to a new view, reusing the buffer.\n  function toBufferView(bufferSource) {\n    return new Uint8Array(\n      bufferSource.buffer || bufferSource,\n      bufferSource.byteOffset || 0,\n      getByteLength(bufferSource)\n    );\n  }\n\n  // We use this string twice, so give it a name for minification.\n  var tagDataView = '[object DataView]';\n\n  // Internal recursive comparison function for `_.isEqual`.\n  function eq(a, b, aStack, bStack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) return a !== 0 || 1 / a === 1 / b;\n    // `null` or `undefined` only equal to itself (strict comparison).\n    if (a == null || b == null) return false;\n    // `NaN`s are equivalent, but non-reflexive.\n    if (a !== a) return b !== b;\n    // Exhaust primitive checks\n    var type = typeof a;\n    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;\n    return deepEq(a, b, aStack, bStack);\n  }\n\n  // Internal recursive comparison function for `_.isEqual`.\n  function deepEq(a, b, aStack, bStack) {\n    // Unwrap any wrapped objects.\n    if (a instanceof _$1) a = a._wrapped;\n    if (b instanceof _$1) b = b._wrapped;\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className !== toString.call(b)) return false;\n    // Work around a bug in IE 10 - Edge 13.\n    if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {\n      if (!isDataView$1(b)) return false;\n      className = tagDataView;\n    }\n    switch (className) {\n      // These types are compared by value.\n      case '[object RegExp]':\n        // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return '' + a === '' + b;\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive.\n        // Object(NaN) is equivalent to NaN.\n        if (+a !== +a) return +b !== +b;\n        // An `egal` comparison is performed for other numeric values.\n        return +a === 0 ? 1 / +a === 1 / b : +a === +b;\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a === +b;\n      case '[object Symbol]':\n        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);\n      case '[object ArrayBuffer]':\n      case tagDataView:\n        // Coerce to typed array so we can fall through.\n        return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);\n    }\n\n    var areArrays = className === '[object Array]';\n    if (!areArrays && isTypedArray$1(a)) {\n        var byteLength = getByteLength(a);\n        if (byteLength !== getByteLength(b)) return false;\n        if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;\n        areArrays = true;\n    }\n    if (!areArrays) {\n      if (typeof a != 'object' || typeof b != 'object') return false;\n\n      // Objects with different constructors are not equivalent, but `Object`s or `Array`s\n      // from different frames are.\n      var aCtor = a.constructor, bCtor = b.constructor;\n      if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor &&\n                               isFunction$1(bCtor) && bCtor instanceof bCtor)\n                          && ('constructor' in a && 'constructor' in b)) {\n        return false;\n      }\n    }\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n\n    // Initializing stack of traversed objects.\n    // It's done here since we only need them for objects and arrays comparison.\n    aStack = aStack || [];\n    bStack = bStack || [];\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] === a) return bStack[length] === b;\n    }\n\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n\n    // Recursively compare objects and arrays.\n    if (areArrays) {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      length = a.length;\n      if (length !== b.length) return false;\n      // Deep compare the contents, ignoring non-numeric properties.\n      while (length--) {\n        if (!eq(a[length], b[length], aStack, bStack)) return false;\n      }\n    } else {\n      // Deep compare objects.\n      var _keys = keys(a), key;\n      length = _keys.length;\n      // Ensure that both objects contain the same number of properties before comparing deep equality.\n      if (keys(b).length !== length) return false;\n      while (length--) {\n        // Deep compare each member\n        key = _keys[length];\n        if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n    return true;\n  }\n\n  // Perform a deep comparison to check if two objects are equal.\n  function isEqual(a, b) {\n    return eq(a, b);\n  }\n\n  // Retrieve all the enumerable property names of an object.\n  function allKeys(obj) {\n    if (!isObject(obj)) return [];\n    var keys = [];\n    for (var key in obj) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  }\n\n  // Since the regular `Object.prototype.toString` type tests don't work for\n  // some types in IE 11, we use a fingerprinting heuristic instead, based\n  // on the methods. It's not great, but it's the best we got.\n  // The fingerprint method lists are defined below.\n  function ie11fingerprint(methods) {\n    var length = getLength(methods);\n    return function(obj) {\n      if (obj == null) return false;\n      // `Map`, `WeakMap` and `Set` have no enumerable keys.\n      var keys = allKeys(obj);\n      if (getLength(keys)) return false;\n      for (var i = 0; i < length; i++) {\n        if (!isFunction$1(obj[methods[i]])) return false;\n      }\n      // If we are testing against `WeakMap`, we need to ensure that\n      // `obj` doesn't have a `forEach` method in order to distinguish\n      // it from a regular `Map`.\n      return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);\n    };\n  }\n\n  // In the interest of compact minification, we write\n  // each string in the fingerprints only once.\n  var forEachName = 'forEach',\n      hasName = 'has',\n      commonInit = ['clear', 'delete'],\n      mapTail = ['get', hasName, 'set'];\n\n  // `Map`, `WeakMap` and `Set` each have slightly different\n  // combinations of the above sublists.\n  var mapMethods = commonInit.concat(forEachName, mapTail),\n      weakMapMethods = commonInit.concat(mapTail),\n      setMethods = ['add'].concat(commonInit, forEachName, hasName);\n\n  var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');\n\n  var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');\n\n  var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');\n\n  var isWeakSet = tagTester('WeakSet');\n\n  // Retrieve the values of an object's properties.\n  function values(obj) {\n    var _keys = keys(obj);\n    var length = _keys.length;\n    var values = Array(length);\n    for (var i = 0; i < length; i++) {\n      values[i] = obj[_keys[i]];\n    }\n    return values;\n  }\n\n  // Convert an object into a list of `[key, value]` pairs.\n  // The opposite of `_.object` with one argument.\n  function pairs(obj) {\n    var _keys = keys(obj);\n    var length = _keys.length;\n    var pairs = Array(length);\n    for (var i = 0; i < length; i++) {\n      pairs[i] = [_keys[i], obj[_keys[i]]];\n    }\n    return pairs;\n  }\n\n  // Invert the keys and values of an object. The values must be serializable.\n  function invert(obj) {\n    var result = {};\n    var _keys = keys(obj);\n    for (var i = 0, length = _keys.length; i < length; i++) {\n      result[obj[_keys[i]]] = _keys[i];\n    }\n    return result;\n  }\n\n  // Return a sorted list of the function names available on the object.\n  function functions(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (isFunction$1(obj[key])) names.push(key);\n    }\n    return names.sort();\n  }\n\n  // An internal function for creating assigner functions.\n  function createAssigner(keysFunc, defaults) {\n    return function(obj) {\n      var length = arguments.length;\n      if (defaults) obj = Object(obj);\n      if (length < 2 || obj == null) return obj;\n      for (var index = 1; index < length; index++) {\n        var source = arguments[index],\n            keys = keysFunc(source),\n            l = keys.length;\n        for (var i = 0; i < l; i++) {\n          var key = keys[i];\n          if (!defaults || obj[key] === void 0) obj[key] = source[key];\n        }\n      }\n      return obj;\n    };\n  }\n\n  // Extend a given object with all the properties in passed-in object(s).\n  var extend = createAssigner(allKeys);\n\n  // Assigns a given object with all the own properties in the passed-in\n  // object(s).\n  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n  var extendOwn = createAssigner(keys);\n\n  // Fill in a given object with default properties.\n  var defaults = createAssigner(allKeys, true);\n\n  // Create a naked function reference for surrogate-prototype-swapping.\n  function ctor() {\n    return function(){};\n  }\n\n  // An internal function for creating a new object that inherits from another.\n  function baseCreate(prototype) {\n    if (!isObject(prototype)) return {};\n    if (nativeCreate) return nativeCreate(prototype);\n    var Ctor = ctor();\n    Ctor.prototype = prototype;\n    var result = new Ctor;\n    Ctor.prototype = null;\n    return result;\n  }\n\n  // Creates an object that inherits from the given prototype object.\n  // If additional properties are provided then they will be added to the\n  // created object.\n  function create(prototype, props) {\n    var result = baseCreate(prototype);\n    if (props) extendOwn(result, props);\n    return result;\n  }\n\n  // Create a (shallow-cloned) duplicate of an object.\n  function clone(obj) {\n    if (!isObject(obj)) return obj;\n    return isArray(obj) ? obj.slice() : extend({}, obj);\n  }\n\n  // Invokes `interceptor` with the `obj` and then returns `obj`.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  function tap(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  }\n\n  // Normalize a (deep) property `path` to array.\n  // Like `_.iteratee`, this function can be customized.\n  function toPath$1(path) {\n    return isArray(path) ? path : [path];\n  }\n  _$1.toPath = toPath$1;\n\n  // Internal wrapper for `_.toPath` to enable minification.\n  // Similar to `cb` for `_.iteratee`.\n  function toPath(path) {\n    return _$1.toPath(path);\n  }\n\n  // Internal function to obtain a nested property in `obj` along `path`.\n  function deepGet(obj, path) {\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      if (obj == null) return void 0;\n      obj = obj[path[i]];\n    }\n    return length ? obj : void 0;\n  }\n\n  // Get the value of the (deep) property on `path` from `object`.\n  // If any property in `path` does not exist or if the value is\n  // `undefined`, return `defaultValue` instead.\n  // The `path` is normalized through `_.toPath`.\n  function get(object, path, defaultValue) {\n    var value = deepGet(object, toPath(path));\n    return isUndefined(value) ? defaultValue : value;\n  }\n\n  // Shortcut function for checking if an object has a given property directly on\n  // itself (in other words, not on a prototype). Unlike the internal `has`\n  // function, this public version can also traverse nested properties.\n  function has(obj, path) {\n    path = toPath(path);\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      var key = path[i];\n      if (!has$1(obj, key)) return false;\n      obj = obj[key];\n    }\n    return !!length;\n  }\n\n  // Keep the identity function around for default iteratees.\n  function identity(value) {\n    return value;\n  }\n\n  // Returns a predicate for checking whether an object has a given set of\n  // `key:value` pairs.\n  function matcher(attrs) {\n    attrs = extendOwn({}, attrs);\n    return function(obj) {\n      return isMatch(obj, attrs);\n    };\n  }\n\n  // Creates a function that, when passed an object, will traverse that object’s\n  // properties down the given `path`, specified as an array of keys or indices.\n  function property(path) {\n    path = toPath(path);\n    return function(obj) {\n      return deepGet(obj, path);\n    };\n  }\n\n  // Internal function that returns an efficient (for current engines) version\n  // of the passed-in callback, to be repeatedly applied in other Underscore\n  // functions.\n  function optimizeCb(func, context, argCount) {\n    if (context === void 0) return func;\n    switch (argCount == null ? 3 : argCount) {\n      case 1: return function(value) {\n        return func.call(context, value);\n      };\n      // The 2-argument case is omitted because we’re not using it.\n      case 3: return function(value, index, collection) {\n        return func.call(context, value, index, collection);\n      };\n      case 4: return function(accumulator, value, index, collection) {\n        return func.call(context, accumulator, value, index, collection);\n      };\n    }\n    return function() {\n      return func.apply(context, arguments);\n    };\n  }\n\n  // An internal function to generate callbacks that can be applied to each\n  // element in a collection, returning the desired result — either `_.identity`,\n  // an arbitrary callback, a property matcher, or a property accessor.\n  function baseIteratee(value, context, argCount) {\n    if (value == null) return identity;\n    if (isFunction$1(value)) return optimizeCb(value, context, argCount);\n    if (isObject(value) && !isArray(value)) return matcher(value);\n    return property(value);\n  }\n\n  // External wrapper for our callback generator. Users may customize\n  // `_.iteratee` if they want additional predicate/iteratee shorthand styles.\n  // This abstraction hides the internal-only `argCount` argument.\n  function iteratee(value, context) {\n    return baseIteratee(value, context, Infinity);\n  }\n  _$1.iteratee = iteratee;\n\n  // The function we call internally to generate a callback. It invokes\n  // `_.iteratee` if overridden, otherwise `baseIteratee`.\n  function cb(value, context, argCount) {\n    if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context);\n    return baseIteratee(value, context, argCount);\n  }\n\n  // Returns the results of applying the `iteratee` to each element of `obj`.\n  // In contrast to `_.map` it returns an object.\n  function mapObject(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var _keys = keys(obj),\n        length = _keys.length,\n        results = {};\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys[index];\n      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  }\n\n  // Predicate-generating function. Often useful outside of Underscore.\n  function noop(){}\n\n  // Generates a function for a given object that returns a given property.\n  function propertyOf(obj) {\n    if (obj == null) return noop;\n    return function(path) {\n      return get(obj, path);\n    };\n  }\n\n  // Run a function **n** times.\n  function times(n, iteratee, context) {\n    var accum = Array(Math.max(0, n));\n    iteratee = optimizeCb(iteratee, context, 1);\n    for (var i = 0; i < n; i++) accum[i] = iteratee(i);\n    return accum;\n  }\n\n  // Return a random integer between `min` and `max` (inclusive).\n  function random(min, max) {\n    if (max == null) {\n      max = min;\n      min = 0;\n    }\n    return min + Math.floor(Math.random() * (max - min + 1));\n  }\n\n  // A (possibly faster) way to get the current timestamp as an integer.\n  var now = Date.now || function() {\n    return new Date().getTime();\n  };\n\n  // Internal helper to generate functions for escaping and unescaping strings\n  // to/from HTML interpolation.\n  function createEscaper(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  }\n\n  // Internal list of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n\n  // Function for escaping strings to HTML interpolation.\n  var _escape = createEscaper(escapeMap);\n\n  // Internal list of HTML entities for unescaping.\n  var unescapeMap = invert(escapeMap);\n\n  // Function for unescaping strings from HTML interpolation.\n  var _unescape = createEscaper(unescapeMap);\n\n  // By default, Underscore uses ERB-style template delimiters. Change the\n  // following template settings to use alternative delimiters.\n  var templateSettings = _$1.templateSettings = {\n    evaluate: /<%([\\s\\S]+?)%>/g,\n    interpolate: /<%=([\\s\\S]+?)%>/g,\n    escape: /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `_.templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /(.)^/;\n\n  // Certain characters need to be escaped so that they can be put into a\n  // string literal.\n  var escapes = {\n    \"'\": \"'\",\n    '\\\\': '\\\\',\n    '\\r': 'r',\n    '\\n': 'n',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  var escapeRegExp = /\\\\|'|\\r|\\n|\\u2028|\\u2029/g;\n\n  function escapeChar(match) {\n    return '\\\\' + escapes[match];\n  }\n\n  // In order to prevent third-party code injection through\n  // `_.templateSettings.variable`, we test it against the following regular\n  // expression. It is intentionally a bit more liberal than just matching valid\n  // identifiers, but still prevents possible loopholes through defaults or\n  // destructuring assignment.\n  var bareIdentifier = /^\\s*(\\w|\\$)+\\s*$/;\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  // NB: `oldSettings` only exists for backwards compatibility.\n  function template(text, settings, oldSettings) {\n    if (!settings && oldSettings) settings = oldSettings;\n    settings = defaults({}, settings, _$1.templateSettings);\n\n    // Combine delimiters into one regular expression via alternation.\n    var matcher = RegExp([\n      (settings.escape || noMatch).source,\n      (settings.interpolate || noMatch).source,\n      (settings.evaluate || noMatch).source\n    ].join('|') + '|$', 'g');\n\n    // Compile the template source, escaping string literals appropriately.\n    var index = 0;\n    var source = \"__p+='\";\n    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\n      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);\n      index = offset + match.length;\n\n      if (escape) {\n        source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\n      } else if (interpolate) {\n        source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\n      } else if (evaluate) {\n        source += \"';\\n\" + evaluate + \"\\n__p+='\";\n      }\n\n      // Adobe VMs need the match returned to produce the correct offset.\n      return match;\n    });\n    source += \"';\\n\";\n\n    var argument = settings.variable;\n    if (argument) {\n      // Insure against third-party code injection. (CVE-2021-23358)\n      if (!bareIdentifier.test(argument)) throw new Error(\n        'variable is not a bare identifier: ' + argument\n      );\n    } else {\n      // If a variable is not specified, place data values in local scope.\n      source = 'with(obj||{}){\\n' + source + '}\\n';\n      argument = 'obj';\n    }\n\n    source = \"var __t,__p='',__j=Array.prototype.join,\" +\n      \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\n      source + 'return __p;\\n';\n\n    var render;\n    try {\n      render = new Function(argument, '_', source);\n    } catch (e) {\n      e.source = source;\n      throw e;\n    }\n\n    var template = function(data) {\n      return render.call(this, data, _$1);\n    };\n\n    // Provide the compiled source as a convenience for precompilation.\n    template.source = 'function(' + argument + '){\\n' + source + '}';\n\n    return template;\n  }\n\n  // Traverses the children of `obj` along `path`. If a child is a function, it\n  // is invoked with its parent as context. Returns the value of the final\n  // child, or `fallback` if any child is undefined.\n  function result(obj, path, fallback) {\n    path = toPath(path);\n    var length = path.length;\n    if (!length) {\n      return isFunction$1(fallback) ? fallback.call(obj) : fallback;\n    }\n    for (var i = 0; i < length; i++) {\n      var prop = obj == null ? void 0 : obj[path[i]];\n      if (prop === void 0) {\n        prop = fallback;\n        i = length; // Ensure we don't continue iterating.\n      }\n      obj = isFunction$1(prop) ? prop.call(obj) : prop;\n    }\n    return obj;\n  }\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  function uniqueId(prefix) {\n    var id = ++idCounter + '';\n    return prefix ? prefix + id : id;\n  }\n\n  // Start chaining a wrapped Underscore object.\n  function chain(obj) {\n    var instance = _$1(obj);\n    instance._chain = true;\n    return instance;\n  }\n\n  // Internal function to execute `sourceFunc` bound to `context` with optional\n  // `args`. Determines whether to execute a function as a constructor or as a\n  // normal function.\n  function executeBound(sourceFunc, boundFunc, context, callingContext, args) {\n    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);\n    var self = baseCreate(sourceFunc.prototype);\n    var result = sourceFunc.apply(self, args);\n    if (isObject(result)) return result;\n    return self;\n  }\n\n  // Partially apply a function by creating a version that has had some of its\n  // arguments pre-filled, without changing its dynamic `this` context. `_` acts\n  // as a placeholder by default, allowing any combination of arguments to be\n  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.\n  var partial = restArguments(function(func, boundArgs) {\n    var placeholder = partial.placeholder;\n    var bound = function() {\n      var position = 0, length = boundArgs.length;\n      var args = Array(length);\n      for (var i = 0; i < length; i++) {\n        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];\n      }\n      while (position < arguments.length) args.push(arguments[position++]);\n      return executeBound(func, bound, this, this, args);\n    };\n    return bound;\n  });\n\n  partial.placeholder = _$1;\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally).\n  var bind = restArguments(function(func, context, args) {\n    if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');\n    var bound = restArguments(function(callArgs) {\n      return executeBound(func, bound, context, this, args.concat(callArgs));\n    });\n    return bound;\n  });\n\n  // Internal helper for collection methods to determine whether a collection\n  // should be iterated as an array or as an object.\n  // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength\n  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094\n  var isArrayLike = createSizePropertyCheck(getLength);\n\n  // Internal implementation of a recursive `flatten` function.\n  function flatten$1(input, depth, strict, output) {\n    output = output || [];\n    if (!depth && depth !== 0) {\n      depth = Infinity;\n    } else if (depth <= 0) {\n      return output.concat(input);\n    }\n    var idx = output.length;\n    for (var i = 0, length = getLength(input); i < length; i++) {\n      var value = input[i];\n      if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {\n        // Flatten current level of array or arguments object.\n        if (depth > 1) {\n          flatten$1(value, depth - 1, strict, output);\n          idx = output.length;\n        } else {\n          var j = 0, len = value.length;\n          while (j < len) output[idx++] = value[j++];\n        }\n      } else if (!strict) {\n        output[idx++] = value;\n      }\n    }\n    return output;\n  }\n\n  // Bind a number of an object's methods to that object. Remaining arguments\n  // are the method names to be bound. Useful for ensuring that all callbacks\n  // defined on an object belong to it.\n  var bindAll = restArguments(function(obj, keys) {\n    keys = flatten$1(keys, false, false);\n    var index = keys.length;\n    if (index < 1) throw new Error('bindAll must be passed function names');\n    while (index--) {\n      var key = keys[index];\n      obj[key] = bind(obj[key], obj);\n    }\n    return obj;\n  });\n\n  // Memoize an expensive function by storing its results.\n  function memoize(func, hasher) {\n    var memoize = function(key) {\n      var cache = memoize.cache;\n      var address = '' + (hasher ? hasher.apply(this, arguments) : key);\n      if (!has$1(cache, address)) cache[address] = func.apply(this, arguments);\n      return cache[address];\n    };\n    memoize.cache = {};\n    return memoize;\n  }\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  var delay = restArguments(function(func, wait, args) {\n    return setTimeout(function() {\n      return func.apply(null, args);\n    }, wait);\n  });\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  var defer = partial(delay, _$1, 1);\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time. Normally, the throttled function will run\n  // as much as it can, without ever going more than once per `wait` duration;\n  // but if you'd like to disable the execution on the leading edge, pass\n  // `{leading: false}`. To disable execution on the trailing edge, ditto.\n  function throttle(func, wait, options) {\n    var timeout, context, args, result;\n    var previous = 0;\n    if (!options) options = {};\n\n    var later = function() {\n      previous = options.leading === false ? 0 : now();\n      timeout = null;\n      result = func.apply(context, args);\n      if (!timeout) context = args = null;\n    };\n\n    var throttled = function() {\n      var _now = now();\n      if (!previous && options.leading === false) previous = _now;\n      var remaining = wait - (_now - previous);\n      context = this;\n      args = arguments;\n      if (remaining <= 0 || remaining > wait) {\n        if (timeout) {\n          clearTimeout(timeout);\n          timeout = null;\n        }\n        previous = _now;\n        result = func.apply(context, args);\n        if (!timeout) context = args = null;\n      } else if (!timeout && options.trailing !== false) {\n        timeout = setTimeout(later, remaining);\n      }\n      return result;\n    };\n\n    throttled.cancel = function() {\n      clearTimeout(timeout);\n      previous = 0;\n      timeout = context = args = null;\n    };\n\n    return throttled;\n  }\n\n  // When a sequence of calls of the returned function ends, the argument\n  // function is triggered. The end of a sequence is defined by the `wait`\n  // parameter. If `immediate` is passed, the argument function will be\n  // triggered at the beginning of the sequence instead of at the end.\n  function debounce(func, wait, immediate) {\n    var timeout, previous, args, result, context;\n\n    var later = function() {\n      var passed = now() - previous;\n      if (wait > passed) {\n        timeout = setTimeout(later, wait - passed);\n      } else {\n        timeout = null;\n        if (!immediate) result = func.apply(context, args);\n        // This check is needed because `func` can recursively invoke `debounced`.\n        if (!timeout) args = context = null;\n      }\n    };\n\n    var debounced = restArguments(function(_args) {\n      context = this;\n      args = _args;\n      previous = now();\n      if (!timeout) {\n        timeout = setTimeout(later, wait);\n        if (immediate) result = func.apply(context, args);\n      }\n      return result;\n    });\n\n    debounced.cancel = function() {\n      clearTimeout(timeout);\n      timeout = args = context = null;\n    };\n\n    return debounced;\n  }\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  function wrap(func, wrapper) {\n    return partial(wrapper, func);\n  }\n\n  // Returns a negated version of the passed-in predicate.\n  function negate(predicate) {\n    return function() {\n      return !predicate.apply(this, arguments);\n    };\n  }\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  function compose() {\n    var args = arguments;\n    var start = args.length - 1;\n    return function() {\n      var i = start;\n      var result = args[start].apply(this, arguments);\n      while (i--) result = args[i].call(this, result);\n      return result;\n    };\n  }\n\n  // Returns a function that will only be executed on and after the Nth call.\n  function after(times, func) {\n    return function() {\n      if (--times < 1) {\n        return func.apply(this, arguments);\n      }\n    };\n  }\n\n  // Returns a function that will only be executed up to (but not including) the\n  // Nth call.\n  function before(times, func) {\n    var memo;\n    return function() {\n      if (--times > 0) {\n        memo = func.apply(this, arguments);\n      }\n      if (times <= 1) func = null;\n      return memo;\n    };\n  }\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  var once = partial(before, 2);\n\n  // Returns the first key on an object that passes a truth test.\n  function findKey(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = keys(obj), key;\n    for (var i = 0, length = _keys.length; i < length; i++) {\n      key = _keys[i];\n      if (predicate(obj[key], key, obj)) return key;\n    }\n  }\n\n  // Internal function to generate `_.findIndex` and `_.findLastIndex`.\n  function createPredicateIndexFinder(dir) {\n    return function(array, predicate, context) {\n      predicate = cb(predicate, context);\n      var length = getLength(array);\n      var index = dir > 0 ? 0 : length - 1;\n      for (; index >= 0 && index < length; index += dir) {\n        if (predicate(array[index], index, array)) return index;\n      }\n      return -1;\n    };\n  }\n\n  // Returns the first index on an array-like that passes a truth test.\n  var findIndex = createPredicateIndexFinder(1);\n\n  // Returns the last index on an array-like that passes a truth test.\n  var findLastIndex = createPredicateIndexFinder(-1);\n\n  // Use a comparator function to figure out the smallest index at which\n  // an object should be inserted so as to maintain order. Uses binary search.\n  function sortedIndex(array, obj, iteratee, context) {\n    iteratee = cb(iteratee, context, 1);\n    var value = iteratee(obj);\n    var low = 0, high = getLength(array);\n    while (low < high) {\n      var mid = Math.floor((low + high) / 2);\n      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;\n    }\n    return low;\n  }\n\n  // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.\n  function createIndexFinder(dir, predicateFind, sortedIndex) {\n    return function(array, item, idx) {\n      var i = 0, length = getLength(array);\n      if (typeof idx == 'number') {\n        if (dir > 0) {\n          i = idx >= 0 ? idx : Math.max(idx + length, i);\n        } else {\n          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;\n        }\n      } else if (sortedIndex && idx && length) {\n        idx = sortedIndex(array, item);\n        return array[idx] === item ? idx : -1;\n      }\n      if (item !== item) {\n        idx = predicateFind(slice.call(array, i, length), isNaN$1);\n        return idx >= 0 ? idx + i : -1;\n      }\n      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {\n        if (array[idx] === item) return idx;\n      }\n      return -1;\n    };\n  }\n\n  // Return the position of the first occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  var indexOf = createIndexFinder(1, findIndex, sortedIndex);\n\n  // Return the position of the last occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  var lastIndexOf = createIndexFinder(-1, findLastIndex);\n\n  // Return the first value which passes a truth test.\n  function find(obj, predicate, context) {\n    var keyFinder = isArrayLike(obj) ? findIndex : findKey;\n    var key = keyFinder(obj, predicate, context);\n    if (key !== void 0 && key !== -1) return obj[key];\n  }\n\n  // Convenience version of a common use case of `_.find`: getting the first\n  // object containing specific `key:value` pairs.\n  function findWhere(obj, attrs) {\n    return find(obj, matcher(attrs));\n  }\n\n  // The cornerstone for collection functions, an `each`\n  // implementation, aka `forEach`.\n  // Handles raw objects in addition to array-likes. Treats all\n  // sparse array-likes as if they were dense.\n  function each(obj, iteratee, context) {\n    iteratee = optimizeCb(iteratee, context);\n    var i, length;\n    if (isArrayLike(obj)) {\n      for (i = 0, length = obj.length; i < length; i++) {\n        iteratee(obj[i], i, obj);\n      }\n    } else {\n      var _keys = keys(obj);\n      for (i = 0, length = _keys.length; i < length; i++) {\n        iteratee(obj[_keys[i]], _keys[i], obj);\n      }\n    }\n    return obj;\n  }\n\n  // Return the results of applying the iteratee to each element.\n  function map(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length,\n        results = Array(length);\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      results[index] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  }\n\n  // Internal helper to create a reducing function, iterating left or right.\n  function createReduce(dir) {\n    // Wrap code that reassigns argument variables in a separate function than\n    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)\n    var reducer = function(obj, iteratee, memo, initial) {\n      var _keys = !isArrayLike(obj) && keys(obj),\n          length = (_keys || obj).length,\n          index = dir > 0 ? 0 : length - 1;\n      if (!initial) {\n        memo = obj[_keys ? _keys[index] : index];\n        index += dir;\n      }\n      for (; index >= 0 && index < length; index += dir) {\n        var currentKey = _keys ? _keys[index] : index;\n        memo = iteratee(memo, obj[currentKey], currentKey, obj);\n      }\n      return memo;\n    };\n\n    return function(obj, iteratee, memo, context) {\n      var initial = arguments.length >= 3;\n      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);\n    };\n  }\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`.\n  var reduce = createReduce(1);\n\n  // The right-associative version of reduce, also known as `foldr`.\n  var reduceRight = createReduce(-1);\n\n  // Return all the elements that pass a truth test.\n  function filter(obj, predicate, context) {\n    var results = [];\n    predicate = cb(predicate, context);\n    each(obj, function(value, index, list) {\n      if (predicate(value, index, list)) results.push(value);\n    });\n    return results;\n  }\n\n  // Return all the elements for which a truth test fails.\n  function reject(obj, predicate, context) {\n    return filter(obj, negate(cb(predicate)), context);\n  }\n\n  // Determine whether all of the elements pass a truth test.\n  function every(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      if (!predicate(obj[currentKey], currentKey, obj)) return false;\n    }\n    return true;\n  }\n\n  // Determine if at least one element in the object passes a truth test.\n  function some(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      if (predicate(obj[currentKey], currentKey, obj)) return true;\n    }\n    return false;\n  }\n\n  // Determine if the array or object contains a given item (using `===`).\n  function contains(obj, item, fromIndex, guard) {\n    if (!isArrayLike(obj)) obj = values(obj);\n    if (typeof fromIndex != 'number' || guard) fromIndex = 0;\n    return indexOf(obj, item, fromIndex) >= 0;\n  }\n\n  // Invoke a method (with arguments) on every item in a collection.\n  var invoke = restArguments(function(obj, path, args) {\n    var contextPath, func;\n    if (isFunction$1(path)) {\n      func = path;\n    } else {\n      path = toPath(path);\n      contextPath = path.slice(0, -1);\n      path = path[path.length - 1];\n    }\n    return map(obj, function(context) {\n      var method = func;\n      if (!method) {\n        if (contextPath && contextPath.length) {\n          context = deepGet(context, contextPath);\n        }\n        if (context == null) return void 0;\n        method = context[path];\n      }\n      return method == null ? method : method.apply(context, args);\n    });\n  });\n\n  // Convenience version of a common use case of `_.map`: fetching a property.\n  function pluck(obj, key) {\n    return map(obj, property(key));\n  }\n\n  // Convenience version of a common use case of `_.filter`: selecting only\n  // objects containing specific `key:value` pairs.\n  function where(obj, attrs) {\n    return filter(obj, matcher(attrs));\n  }\n\n  // Return the maximum element (or element-based computation).\n  function max(obj, iteratee, context) {\n    var result = -Infinity, lastComputed = -Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value > result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  }\n\n  // Return the minimum element (or element-based computation).\n  function min(obj, iteratee, context) {\n    var result = Infinity, lastComputed = Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value < result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed < lastComputed || computed === Infinity && result === Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  }\n\n  // Sample **n** random values from a collection using the modern version of the\n  // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).\n  // If **n** is not specified, returns a single random element.\n  // The internal `guard` argument allows it to work with `_.map`.\n  function sample(obj, n, guard) {\n    if (n == null || guard) {\n      if (!isArrayLike(obj)) obj = values(obj);\n      return obj[random(obj.length - 1)];\n    }\n    var sample = isArrayLike(obj) ? clone(obj) : values(obj);\n    var length = getLength(sample);\n    n = Math.max(Math.min(n, length), 0);\n    var last = length - 1;\n    for (var index = 0; index < n; index++) {\n      var rand = random(index, last);\n      var temp = sample[index];\n      sample[index] = sample[rand];\n      sample[rand] = temp;\n    }\n    return sample.slice(0, n);\n  }\n\n  // Shuffle a collection.\n  function shuffle(obj) {\n    return sample(obj, Infinity);\n  }\n\n  // Sort the object's values by a criterion produced by an iteratee.\n  function sortBy(obj, iteratee, context) {\n    var index = 0;\n    iteratee = cb(iteratee, context);\n    return pluck(map(obj, function(value, key, list) {\n      return {\n        value: value,\n        index: index++,\n        criteria: iteratee(value, key, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria;\n      var b = right.criteria;\n      if (a !== b) {\n        if (a > b || a === void 0) return 1;\n        if (a < b || b === void 0) return -1;\n      }\n      return left.index - right.index;\n    }), 'value');\n  }\n\n  // An internal function used for aggregate \"group by\" operations.\n  function group(behavior, partition) {\n    return function(obj, iteratee, context) {\n      var result = partition ? [[], []] : {};\n      iteratee = cb(iteratee, context);\n      each(obj, function(value, index) {\n        var key = iteratee(value, index, obj);\n        behavior(result, value, key);\n      });\n      return result;\n    };\n  }\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  var groupBy = group(function(result, value, key) {\n    if (has$1(result, key)) result[key].push(value); else result[key] = [value];\n  });\n\n  // Indexes the object's values by a criterion, similar to `_.groupBy`, but for\n  // when you know that your index values will be unique.\n  var indexBy = group(function(result, value, key) {\n    result[key] = value;\n  });\n\n  // Counts instances of an object that group by a certain criterion. Pass\n  // either a string attribute to count by, or a function that returns the\n  // criterion.\n  var countBy = group(function(result, value, key) {\n    if (has$1(result, key)) result[key]++; else result[key] = 1;\n  });\n\n  // Split a collection into two arrays: one whose elements all pass the given\n  // truth test, and one whose elements all do not pass the truth test.\n  var partition = group(function(result, value, pass) {\n    result[pass ? 0 : 1].push(value);\n  }, true);\n\n  // Safely create a real, live array from anything iterable.\n  var reStrSymbol = /[^\\ud800-\\udfff]|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff]/g;\n  function toArray(obj) {\n    if (!obj) return [];\n    if (isArray(obj)) return slice.call(obj);\n    if (isString(obj)) {\n      // Keep surrogate pair characters together.\n      return obj.match(reStrSymbol);\n    }\n    if (isArrayLike(obj)) return map(obj, identity);\n    return values(obj);\n  }\n\n  // Return the number of elements in a collection.\n  function size(obj) {\n    if (obj == null) return 0;\n    return isArrayLike(obj) ? obj.length : keys(obj).length;\n  }\n\n  // Internal `_.pick` helper function to determine whether `key` is an enumerable\n  // property name of `obj`.\n  function keyInObj(value, key, obj) {\n    return key in obj;\n  }\n\n  // Return a copy of the object only containing the allowed properties.\n  var pick = restArguments(function(obj, keys) {\n    var result = {}, iteratee = keys[0];\n    if (obj == null) return result;\n    if (isFunction$1(iteratee)) {\n      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);\n      keys = allKeys(obj);\n    } else {\n      iteratee = keyInObj;\n      keys = flatten$1(keys, false, false);\n      obj = Object(obj);\n    }\n    for (var i = 0, length = keys.length; i < length; i++) {\n      var key = keys[i];\n      var value = obj[key];\n      if (iteratee(value, key, obj)) result[key] = value;\n    }\n    return result;\n  });\n\n  // Return a copy of the object without the disallowed properties.\n  var omit = restArguments(function(obj, keys) {\n    var iteratee = keys[0], context;\n    if (isFunction$1(iteratee)) {\n      iteratee = negate(iteratee);\n      if (keys.length > 1) context = keys[1];\n    } else {\n      keys = map(flatten$1(keys, false, false), String);\n      iteratee = function(value, key) {\n        return !contains(keys, key);\n      };\n    }\n    return pick(obj, iteratee, context);\n  });\n\n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N.\n  function initial(array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n  }\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. The **guard** check allows it to work with `_.map`.\n  function first(array, n, guard) {\n    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];\n    if (n == null || guard) return array[0];\n    return initial(array, array.length - n);\n  }\n\n  // Returns everything but the first entry of the `array`. Especially useful on\n  // the `arguments` object. Passing an **n** will return the rest N values in the\n  // `array`.\n  function rest(array, n, guard) {\n    return slice.call(array, n == null || guard ? 1 : n);\n  }\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array.\n  function last(array, n, guard) {\n    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];\n    if (n == null || guard) return array[array.length - 1];\n    return rest(array, Math.max(0, array.length - n));\n  }\n\n  // Trim out all falsy values from an array.\n  function compact(array) {\n    return filter(array, Boolean);\n  }\n\n  // Flatten out an array, either recursively (by default), or up to `depth`.\n  // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.\n  function flatten(array, depth) {\n    return flatten$1(array, depth, false);\n  }\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  var difference = restArguments(function(array, rest) {\n    rest = flatten$1(rest, true, true);\n    return filter(array, function(value){\n      return !contains(rest, value);\n    });\n  });\n\n  // Return a version of the array that does not contain the specified value(s).\n  var without = restArguments(function(array, otherArrays) {\n    return difference(array, otherArrays);\n  });\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // The faster algorithm will not work with an iteratee if the iteratee\n  // is not a one-to-one function, so providing an iteratee will disable\n  // the faster algorithm.\n  function uniq(array, isSorted, iteratee, context) {\n    if (!isBoolean(isSorted)) {\n      context = iteratee;\n      iteratee = isSorted;\n      isSorted = false;\n    }\n    if (iteratee != null) iteratee = cb(iteratee, context);\n    var result = [];\n    var seen = [];\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var value = array[i],\n          computed = iteratee ? iteratee(value, i, array) : value;\n      if (isSorted && !iteratee) {\n        if (!i || seen !== computed) result.push(value);\n        seen = computed;\n      } else if (iteratee) {\n        if (!contains(seen, computed)) {\n          seen.push(computed);\n          result.push(value);\n        }\n      } else if (!contains(result, value)) {\n        result.push(value);\n      }\n    }\n    return result;\n  }\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  var union = restArguments(function(arrays) {\n    return uniq(flatten$1(arrays, true, true));\n  });\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays.\n  function intersection(array) {\n    var result = [];\n    var argsLength = arguments.length;\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var item = array[i];\n      if (contains(result, item)) continue;\n      var j;\n      for (j = 1; j < argsLength; j++) {\n        if (!contains(arguments[j], item)) break;\n      }\n      if (j === argsLength) result.push(item);\n    }\n    return result;\n  }\n\n  // Complement of zip. Unzip accepts an array of arrays and groups\n  // each array's elements on shared indices.\n  function unzip(array) {\n    var length = array && max(array, getLength).length || 0;\n    var result = Array(length);\n\n    for (var index = 0; index < length; index++) {\n      result[index] = pluck(array, index);\n    }\n    return result;\n  }\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  var zip = restArguments(unzip);\n\n  // Converts lists into objects. Pass either a single array of `[key, value]`\n  // pairs, or two parallel arrays of the same length -- one of keys, and one of\n  // the corresponding values. Passing by pairs is the reverse of `_.pairs`.\n  function object(list, values) {\n    var result = {};\n    for (var i = 0, length = getLength(list); i < length; i++) {\n      if (values) {\n        result[list[i]] = values[i];\n      } else {\n        result[list[i][0]] = list[i][1];\n      }\n    }\n    return result;\n  }\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](https://docs.python.org/library/functions.html#range).\n  function range(start, stop, step) {\n    if (stop == null) {\n      stop = start || 0;\n      start = 0;\n    }\n    if (!step) {\n      step = stop < start ? -1 : 1;\n    }\n\n    var length = Math.max(Math.ceil((stop - start) / step), 0);\n    var range = Array(length);\n\n    for (var idx = 0; idx < length; idx++, start += step) {\n      range[idx] = start;\n    }\n\n    return range;\n  }\n\n  // Chunk a single array into multiple arrays, each containing `count` or fewer\n  // items.\n  function chunk(array, count) {\n    if (count == null || count < 1) return [];\n    var result = [];\n    var i = 0, length = array.length;\n    while (i < length) {\n      result.push(slice.call(array, i, i += count));\n    }\n    return result;\n  }\n\n  // Helper function to continue chaining intermediate results.\n  function chainResult(instance, obj) {\n    return instance._chain ? _$1(obj).chain() : obj;\n  }\n\n  // Add your own custom functions to the Underscore object.\n  function mixin(obj) {\n    each(functions(obj), function(name) {\n      var func = _$1[name] = obj[name];\n      _$1.prototype[name] = function() {\n        var args = [this._wrapped];\n        push.apply(args, arguments);\n        return chainResult(this, func.apply(_$1, args));\n      };\n    });\n    return _$1;\n  }\n\n  // Add all mutator `Array` functions to the wrapper.\n  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    _$1.prototype[name] = function() {\n      var obj = this._wrapped;\n      if (obj != null) {\n        method.apply(obj, arguments);\n        if ((name === 'shift' || name === 'splice') && obj.length === 0) {\n          delete obj[0];\n        }\n      }\n      return chainResult(this, obj);\n    };\n  });\n\n  // Add all accessor `Array` functions to the wrapper.\n  each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    _$1.prototype[name] = function() {\n      var obj = this._wrapped;\n      if (obj != null) obj = method.apply(obj, arguments);\n      return chainResult(this, obj);\n    };\n  });\n\n  // Named Exports\n\n  var allExports = {\n    __proto__: null,\n    VERSION: VERSION,\n    restArguments: restArguments,\n    isObject: isObject,\n    isNull: isNull,\n    isUndefined: isUndefined,\n    isBoolean: isBoolean,\n    isElement: isElement,\n    isString: isString,\n    isNumber: isNumber,\n    isDate: isDate,\n    isRegExp: isRegExp,\n    isError: isError,\n    isSymbol: isSymbol,\n    isArrayBuffer: isArrayBuffer,\n    isDataView: isDataView$1,\n    isArray: isArray,\n    isFunction: isFunction$1,\n    isArguments: isArguments$1,\n    isFinite: isFinite$1,\n    isNaN: isNaN$1,\n    isTypedArray: isTypedArray$1,\n    isEmpty: isEmpty,\n    isMatch: isMatch,\n    isEqual: isEqual,\n    isMap: isMap,\n    isWeakMap: isWeakMap,\n    isSet: isSet,\n    isWeakSet: isWeakSet,\n    keys: keys,\n    allKeys: allKeys,\n    values: values,\n    pairs: pairs,\n    invert: invert,\n    functions: functions,\n    methods: functions,\n    extend: extend,\n    extendOwn: extendOwn,\n    assign: extendOwn,\n    defaults: defaults,\n    create: create,\n    clone: clone,\n    tap: tap,\n    get: get,\n    has: has,\n    mapObject: mapObject,\n    identity: identity,\n    constant: constant,\n    noop: noop,\n    toPath: toPath$1,\n    property: property,\n    propertyOf: propertyOf,\n    matcher: matcher,\n    matches: matcher,\n    times: times,\n    random: random,\n    now: now,\n    escape: _escape,\n    unescape: _unescape,\n    templateSettings: templateSettings,\n    template: template,\n    result: result,\n    uniqueId: uniqueId,\n    chain: chain,\n    iteratee: iteratee,\n    partial: partial,\n    bind: bind,\n    bindAll: bindAll,\n    memoize: memoize,\n    delay: delay,\n    defer: defer,\n    throttle: throttle,\n    debounce: debounce,\n    wrap: wrap,\n    negate: negate,\n    compose: compose,\n    after: after,\n    before: before,\n    once: once,\n    findKey: findKey,\n    findIndex: findIndex,\n    findLastIndex: findLastIndex,\n    sortedIndex: sortedIndex,\n    indexOf: indexOf,\n    lastIndexOf: lastIndexOf,\n    find: find,\n    detect: find,\n    findWhere: findWhere,\n    each: each,\n    forEach: each,\n    map: map,\n    collect: map,\n    reduce: reduce,\n    foldl: reduce,\n    inject: reduce,\n    reduceRight: reduceRight,\n    foldr: reduceRight,\n    filter: filter,\n    select: filter,\n    reject: reject,\n    every: every,\n    all: every,\n    some: some,\n    any: some,\n    contains: contains,\n    includes: contains,\n    include: contains,\n    invoke: invoke,\n    pluck: pluck,\n    where: where,\n    max: max,\n    min: min,\n    shuffle: shuffle,\n    sample: sample,\n    sortBy: sortBy,\n    groupBy: groupBy,\n    indexBy: indexBy,\n    countBy: countBy,\n    partition: partition,\n    toArray: toArray,\n    size: size,\n    pick: pick,\n    omit: omit,\n    first: first,\n    head: first,\n    take: first,\n    initial: initial,\n    last: last,\n    rest: rest,\n    tail: rest,\n    drop: rest,\n    compact: compact,\n    flatten: flatten,\n    without: without,\n    uniq: uniq,\n    unique: uniq,\n    union: union,\n    intersection: intersection,\n    difference: difference,\n    unzip: unzip,\n    transpose: unzip,\n    zip: zip,\n    object: object,\n    range: range,\n    chunk: chunk,\n    mixin: mixin,\n    'default': _$1\n  };\n\n  // Default Export\n\n  // Add all of the Underscore functions to the wrapper object.\n  var _ = mixin(allExports);\n  // Legacy Node.js API.\n  _._ = _;\n\n  return _;\n\n})));\n//# sourceMappingURL=underscore-umd.js.map\n"
  },
  {
    "path": "docs/sphinx/_build/_static/underscore-1.3.1.js",
    "content": "//     Underscore.js 1.3.1\n//     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.\n//     Underscore is freely distributable under the MIT license.\n//     Portions of Underscore are inspired or borrowed from Prototype,\n//     Oliver Steele's Functional, and John Resig's Micro-Templating.\n//     For all details and documentation:\n//     http://documentcloud.github.com/underscore\n\n(function() {\n\n  // Baseline setup\n  // --------------\n\n  // Establish the root object, `window` in the browser, or `global` on the server.\n  var root = this;\n\n  // Save the previous value of the `_` variable.\n  var previousUnderscore = root._;\n\n  // Establish the object that gets returned to break out of a loop iteration.\n  var breaker = {};\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var slice            = ArrayProto.slice,\n      unshift          = ArrayProto.unshift,\n      toString         = ObjProto.toString,\n      hasOwnProperty   = ObjProto.hasOwnProperty;\n\n  // All **ECMAScript 5** native function implementations that we hope to use\n  // are declared here.\n  var\n    nativeForEach      = ArrayProto.forEach,\n    nativeMap          = ArrayProto.map,\n    nativeReduce       = ArrayProto.reduce,\n    nativeReduceRight  = ArrayProto.reduceRight,\n    nativeFilter       = ArrayProto.filter,\n    nativeEvery        = ArrayProto.every,\n    nativeSome         = ArrayProto.some,\n    nativeIndexOf      = ArrayProto.indexOf,\n    nativeLastIndexOf  = ArrayProto.lastIndexOf,\n    nativeIsArray      = Array.isArray,\n    nativeKeys         = Object.keys,\n    nativeBind         = FuncProto.bind;\n\n  // Create a safe reference to the Underscore object for use below.\n  var _ = function(obj) { return new wrapper(obj); };\n\n  // Export the Underscore object for **Node.js**, with\n  // backwards-compatibility for the old `require()` API. If we're in\n  // the browser, add `_` as a global object via a string identifier,\n  // for Closure Compiler \"advanced\" mode.\n  if (typeof exports !== 'undefined') {\n    if (typeof module !== 'undefined' && module.exports) {\n      exports = module.exports = _;\n    }\n    exports._ = _;\n  } else {\n    root['_'] = _;\n  }\n\n  // Current version.\n  _.VERSION = '1.3.1';\n\n  // Collection Functions\n  // --------------------\n\n  // The cornerstone, an `each` implementation, aka `forEach`.\n  // Handles objects with the built-in `forEach`, arrays, and raw objects.\n  // Delegates to **ECMAScript 5**'s native `forEach` if available.\n  var each = _.each = _.forEach = function(obj, iterator, context) {\n    if (obj == null) return;\n    if (nativeForEach && obj.forEach === nativeForEach) {\n      obj.forEach(iterator, context);\n    } else if (obj.length === +obj.length) {\n      for (var i = 0, l = obj.length; i < l; i++) {\n        if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;\n      }\n    } else {\n      for (var key in obj) {\n        if (_.has(obj, key)) {\n          if (iterator.call(context, obj[key], key, obj) === breaker) return;\n        }\n      }\n    }\n  };\n\n  // Return the results of applying the iterator to each element.\n  // Delegates to **ECMAScript 5**'s native `map` if available.\n  _.map = _.collect = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);\n    each(obj, function(value, index, list) {\n      results[results.length] = iterator.call(context, value, index, list);\n    });\n    if (obj.length === +obj.length) results.length = obj.length;\n    return results;\n  };\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.\n  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {\n    var initial = arguments.length > 2;\n    if (obj == null) obj = [];\n    if (nativeReduce && obj.reduce === nativeReduce) {\n      if (context) iterator = _.bind(iterator, context);\n      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);\n    }\n    each(obj, function(value, index, list) {\n      if (!initial) {\n        memo = value;\n        initial = true;\n      } else {\n        memo = iterator.call(context, memo, value, index, list);\n      }\n    });\n    if (!initial) throw new TypeError('Reduce of empty array with no initial value');\n    return memo;\n  };\n\n  // The right-associative version of reduce, also known as `foldr`.\n  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.\n  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {\n    var initial = arguments.length > 2;\n    if (obj == null) obj = [];\n    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {\n      if (context) iterator = _.bind(iterator, context);\n      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);\n    }\n    var reversed = _.toArray(obj).reverse();\n    if (context && !initial) iterator = _.bind(iterator, context);\n    return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);\n  };\n\n  // Return the first value which passes a truth test. Aliased as `detect`.\n  _.find = _.detect = function(obj, iterator, context) {\n    var result;\n    any(obj, function(value, index, list) {\n      if (iterator.call(context, value, index, list)) {\n        result = value;\n        return true;\n      }\n    });\n    return result;\n  };\n\n  // Return all the elements that pass a truth test.\n  // Delegates to **ECMAScript 5**'s native `filter` if available.\n  // Aliased as `select`.\n  _.filter = _.select = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);\n    each(obj, function(value, index, list) {\n      if (iterator.call(context, value, index, list)) results[results.length] = value;\n    });\n    return results;\n  };\n\n  // Return all the elements for which a truth test fails.\n  _.reject = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    each(obj, function(value, index, list) {\n      if (!iterator.call(context, value, index, list)) results[results.length] = value;\n    });\n    return results;\n  };\n\n  // Determine whether all of the elements match a truth test.\n  // Delegates to **ECMAScript 5**'s native `every` if available.\n  // Aliased as `all`.\n  _.every = _.all = function(obj, iterator, context) {\n    var result = true;\n    if (obj == null) return result;\n    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);\n    each(obj, function(value, index, list) {\n      if (!(result = result && iterator.call(context, value, index, list))) return breaker;\n    });\n    return result;\n  };\n\n  // Determine if at least one element in the object matches a truth test.\n  // Delegates to **ECMAScript 5**'s native `some` if available.\n  // Aliased as `any`.\n  var any = _.some = _.any = function(obj, iterator, context) {\n    iterator || (iterator = _.identity);\n    var result = false;\n    if (obj == null) return result;\n    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);\n    each(obj, function(value, index, list) {\n      if (result || (result = iterator.call(context, value, index, list))) return breaker;\n    });\n    return !!result;\n  };\n\n  // Determine if a given value is included in the array or object using `===`.\n  // Aliased as `contains`.\n  _.include = _.contains = function(obj, target) {\n    var found = false;\n    if (obj == null) return found;\n    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;\n    found = any(obj, function(value) {\n      return value === target;\n    });\n    return found;\n  };\n\n  // Invoke a method (with arguments) on every item in a collection.\n  _.invoke = function(obj, method) {\n    var args = slice.call(arguments, 2);\n    return _.map(obj, function(value) {\n      return (_.isFunction(method) ? method || value : value[method]).apply(value, args);\n    });\n  };\n\n  // Convenience version of a common use case of `map`: fetching a property.\n  _.pluck = function(obj, key) {\n    return _.map(obj, function(value){ return value[key]; });\n  };\n\n  // Return the maximum element or (element-based computation).\n  _.max = function(obj, iterator, context) {\n    if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);\n    if (!iterator && _.isEmpty(obj)) return -Infinity;\n    var result = {computed : -Infinity};\n    each(obj, function(value, index, list) {\n      var computed = iterator ? iterator.call(context, value, index, list) : value;\n      computed >= result.computed && (result = {value : value, computed : computed});\n    });\n    return result.value;\n  };\n\n  // Return the minimum element (or element-based computation).\n  _.min = function(obj, iterator, context) {\n    if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);\n    if (!iterator && _.isEmpty(obj)) return Infinity;\n    var result = {computed : Infinity};\n    each(obj, function(value, index, list) {\n      var computed = iterator ? iterator.call(context, value, index, list) : value;\n      computed < result.computed && (result = {value : value, computed : computed});\n    });\n    return result.value;\n  };\n\n  // Shuffle an array.\n  _.shuffle = function(obj) {\n    var shuffled = [], rand;\n    each(obj, function(value, index, list) {\n      if (index == 0) {\n        shuffled[0] = value;\n      } else {\n        rand = Math.floor(Math.random() * (index + 1));\n        shuffled[index] = shuffled[rand];\n        shuffled[rand] = value;\n      }\n    });\n    return shuffled;\n  };\n\n  // Sort the object's values by a criterion produced by an iterator.\n  _.sortBy = function(obj, iterator, context) {\n    return _.pluck(_.map(obj, function(value, index, list) {\n      return {\n        value : value,\n        criteria : iterator.call(context, value, index, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria, b = right.criteria;\n      return a < b ? -1 : a > b ? 1 : 0;\n    }), 'value');\n  };\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  _.groupBy = function(obj, val) {\n    var result = {};\n    var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };\n    each(obj, function(value, index) {\n      var key = iterator(value, index);\n      (result[key] || (result[key] = [])).push(value);\n    });\n    return result;\n  };\n\n  // Use a comparator function to figure out at what index an object should\n  // be inserted so as to maintain order. Uses binary search.\n  _.sortedIndex = function(array, obj, iterator) {\n    iterator || (iterator = _.identity);\n    var low = 0, high = array.length;\n    while (low < high) {\n      var mid = (low + high) >> 1;\n      iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;\n    }\n    return low;\n  };\n\n  // Safely convert anything iterable into a real, live array.\n  _.toArray = function(iterable) {\n    if (!iterable)                return [];\n    if (iterable.toArray)         return iterable.toArray();\n    if (_.isArray(iterable))      return slice.call(iterable);\n    if (_.isArguments(iterable))  return slice.call(iterable);\n    return _.values(iterable);\n  };\n\n  // Return the number of elements in an object.\n  _.size = function(obj) {\n    return _.toArray(obj).length;\n  };\n\n  // Array Functions\n  // ---------------\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. Aliased as `head`. The **guard** check allows it to work\n  // with `_.map`.\n  _.first = _.head = function(array, n, guard) {\n    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];\n  };\n\n  // Returns everything but the last entry of the array. Especcialy useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N. The **guard** check allows it to work with\n  // `_.map`.\n  _.initial = function(array, n, guard) {\n    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));\n  };\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array. The **guard** check allows it to work with `_.map`.\n  _.last = function(array, n, guard) {\n    if ((n != null) && !guard) {\n      return slice.call(array, Math.max(array.length - n, 0));\n    } else {\n      return array[array.length - 1];\n    }\n  };\n\n  // Returns everything but the first entry of the array. Aliased as `tail`.\n  // Especially useful on the arguments object. Passing an **index** will return\n  // the rest of the values in the array from that index onward. The **guard**\n  // check allows it to work with `_.map`.\n  _.rest = _.tail = function(array, index, guard) {\n    return slice.call(array, (index == null) || guard ? 1 : index);\n  };\n\n  // Trim out all falsy values from an array.\n  _.compact = function(array) {\n    return _.filter(array, function(value){ return !!value; });\n  };\n\n  // Return a completely flattened version of an array.\n  _.flatten = function(array, shallow) {\n    return _.reduce(array, function(memo, value) {\n      if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));\n      memo[memo.length] = value;\n      return memo;\n    }, []);\n  };\n\n  // Return a version of the array that does not contain the specified value(s).\n  _.without = function(array) {\n    return _.difference(array, slice.call(arguments, 1));\n  };\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // Aliased as `unique`.\n  _.uniq = _.unique = function(array, isSorted, iterator) {\n    var initial = iterator ? _.map(array, iterator) : array;\n    var result = [];\n    _.reduce(initial, function(memo, el, i) {\n      if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {\n        memo[memo.length] = el;\n        result[result.length] = array[i];\n      }\n      return memo;\n    }, []);\n    return result;\n  };\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  _.union = function() {\n    return _.uniq(_.flatten(arguments, true));\n  };\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays. (Aliased as \"intersect\" for back-compat.)\n  _.intersection = _.intersect = function(array) {\n    var rest = slice.call(arguments, 1);\n    return _.filter(_.uniq(array), function(item) {\n      return _.every(rest, function(other) {\n        return _.indexOf(other, item) >= 0;\n      });\n    });\n  };\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  _.difference = function(array) {\n    var rest = _.flatten(slice.call(arguments, 1));\n    return _.filter(array, function(value){ return !_.include(rest, value); });\n  };\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  _.zip = function() {\n    var args = slice.call(arguments);\n    var length = _.max(_.pluck(args, 'length'));\n    var results = new Array(length);\n    for (var i = 0; i < length; i++) results[i] = _.pluck(args, \"\" + i);\n    return results;\n  };\n\n  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),\n  // we need this function. Return the position of the first occurrence of an\n  // item in an array, or -1 if the item is not included in the array.\n  // Delegates to **ECMAScript 5**'s native `indexOf` if available.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  _.indexOf = function(array, item, isSorted) {\n    if (array == null) return -1;\n    var i, l;\n    if (isSorted) {\n      i = _.sortedIndex(array, item);\n      return array[i] === item ? i : -1;\n    }\n    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);\n    for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;\n    return -1;\n  };\n\n  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.\n  _.lastIndexOf = function(array, item) {\n    if (array == null) return -1;\n    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);\n    var i = array.length;\n    while (i--) if (i in array && array[i] === item) return i;\n    return -1;\n  };\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](http://docs.python.org/library/functions.html#range).\n  _.range = function(start, stop, step) {\n    if (arguments.length <= 1) {\n      stop = start || 0;\n      start = 0;\n    }\n    step = arguments[2] || 1;\n\n    var len = Math.max(Math.ceil((stop - start) / step), 0);\n    var idx = 0;\n    var range = new Array(len);\n\n    while(idx < len) {\n      range[idx++] = start;\n      start += step;\n    }\n\n    return range;\n  };\n\n  // Function (ahem) Functions\n  // ------------------\n\n  // Reusable constructor function for prototype setting.\n  var ctor = function(){};\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally). Binding with arguments is also known as `curry`.\n  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.\n  // We check for `func.bind` first, to fail fast when `func` is undefined.\n  _.bind = function bind(func, context) {\n    var bound, args;\n    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));\n    if (!_.isFunction(func)) throw new TypeError;\n    args = slice.call(arguments, 2);\n    return bound = function() {\n      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));\n      ctor.prototype = func.prototype;\n      var self = new ctor;\n      var result = func.apply(self, args.concat(slice.call(arguments)));\n      if (Object(result) === result) return result;\n      return self;\n    };\n  };\n\n  // Bind all of an object's methods to that object. Useful for ensuring that\n  // all callbacks defined on an object belong to it.\n  _.bindAll = function(obj) {\n    var funcs = slice.call(arguments, 1);\n    if (funcs.length == 0) funcs = _.functions(obj);\n    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });\n    return obj;\n  };\n\n  // Memoize an expensive function by storing its results.\n  _.memoize = function(func, hasher) {\n    var memo = {};\n    hasher || (hasher = _.identity);\n    return function() {\n      var key = hasher.apply(this, arguments);\n      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));\n    };\n  };\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  _.delay = function(func, wait) {\n    var args = slice.call(arguments, 2);\n    return setTimeout(function(){ return func.apply(func, args); }, wait);\n  };\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  _.defer = function(func) {\n    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));\n  };\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time.\n  _.throttle = function(func, wait) {\n    var context, args, timeout, throttling, more;\n    var whenDone = _.debounce(function(){ more = throttling = false; }, wait);\n    return function() {\n      context = this; args = arguments;\n      var later = function() {\n        timeout = null;\n        if (more) func.apply(context, args);\n        whenDone();\n      };\n      if (!timeout) timeout = setTimeout(later, wait);\n      if (throttling) {\n        more = true;\n      } else {\n        func.apply(context, args);\n      }\n      whenDone();\n      throttling = true;\n    };\n  };\n\n  // Returns a function, that, as long as it continues to be invoked, will not\n  // be triggered. The function will be called after it stops being called for\n  // N milliseconds.\n  _.debounce = function(func, wait) {\n    var timeout;\n    return function() {\n      var context = this, args = arguments;\n      var later = function() {\n        timeout = null;\n        func.apply(context, args);\n      };\n      clearTimeout(timeout);\n      timeout = setTimeout(later, wait);\n    };\n  };\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  _.once = function(func) {\n    var ran = false, memo;\n    return function() {\n      if (ran) return memo;\n      ran = true;\n      return memo = func.apply(this, arguments);\n    };\n  };\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  _.wrap = function(func, wrapper) {\n    return function() {\n      var args = [func].concat(slice.call(arguments, 0));\n      return wrapper.apply(this, args);\n    };\n  };\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  _.compose = function() {\n    var funcs = arguments;\n    return function() {\n      var args = arguments;\n      for (var i = funcs.length - 1; i >= 0; i--) {\n        args = [funcs[i].apply(this, args)];\n      }\n      return args[0];\n    };\n  };\n\n  // Returns a function that will only be executed after being called N times.\n  _.after = function(times, func) {\n    if (times <= 0) return func();\n    return function() {\n      if (--times < 1) { return func.apply(this, arguments); }\n    };\n  };\n\n  // Object Functions\n  // ----------------\n\n  // Retrieve the names of an object's properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`\n  _.keys = nativeKeys || function(obj) {\n    if (obj !== Object(obj)) throw new TypeError('Invalid object');\n    var keys = [];\n    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;\n    return keys;\n  };\n\n  // Retrieve the values of an object's properties.\n  _.values = function(obj) {\n    return _.map(obj, _.identity);\n  };\n\n  // Return a sorted list of the function names available on the object.\n  // Aliased as `methods`\n  _.functions = _.methods = function(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (_.isFunction(obj[key])) names.push(key);\n    }\n    return names.sort();\n  };\n\n  // Extend a given object with all the properties in passed-in object(s).\n  _.extend = function(obj) {\n    each(slice.call(arguments, 1), function(source) {\n      for (var prop in source) {\n        obj[prop] = source[prop];\n      }\n    });\n    return obj;\n  };\n\n  // Fill in a given object with default properties.\n  _.defaults = function(obj) {\n    each(slice.call(arguments, 1), function(source) {\n      for (var prop in source) {\n        if (obj[prop] == null) obj[prop] = source[prop];\n      }\n    });\n    return obj;\n  };\n\n  // Create a (shallow-cloned) duplicate of an object.\n  _.clone = function(obj) {\n    if (!_.isObject(obj)) return obj;\n    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);\n  };\n\n  // Invokes interceptor with the obj, and then returns obj.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  _.tap = function(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  };\n\n  // Internal recursive comparison function.\n  function eq(a, b, stack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.\n    if (a === b) return a !== 0 || 1 / a == 1 / b;\n    // A strict comparison is necessary because `null == undefined`.\n    if (a == null || b == null) return a === b;\n    // Unwrap any wrapped objects.\n    if (a._chain) a = a._wrapped;\n    if (b._chain) b = b._wrapped;\n    // Invoke a custom `isEqual` method if one is provided.\n    if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);\n    if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className != toString.call(b)) return false;\n    switch (className) {\n      // Strings, numbers, dates, and booleans are compared by value.\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return a == String(b);\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for\n        // other numeric values.\n        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a == +b;\n      // RegExps are compared by their source patterns and flags.\n      case '[object RegExp]':\n        return a.source == b.source &&\n               a.global == b.global &&\n               a.multiline == b.multiline &&\n               a.ignoreCase == b.ignoreCase;\n    }\n    if (typeof a != 'object' || typeof b != 'object') return false;\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n    var length = stack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (stack[length] == a) return true;\n    }\n    // Add the first object to the stack of traversed objects.\n    stack.push(a);\n    var size = 0, result = true;\n    // Recursively compare objects and arrays.\n    if (className == '[object Array]') {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      size = a.length;\n      result = size == b.length;\n      if (result) {\n        // Deep compare the contents, ignoring non-numeric properties.\n        while (size--) {\n          // Ensure commutative equality for sparse arrays.\n          if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;\n        }\n      }\n    } else {\n      // Objects with different constructors are not equivalent.\n      if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;\n      // Deep compare objects.\n      for (var key in a) {\n        if (_.has(a, key)) {\n          // Count the expected number of properties.\n          size++;\n          // Deep compare each member.\n          if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;\n        }\n      }\n      // Ensure that both objects contain the same number of properties.\n      if (result) {\n        for (key in b) {\n          if (_.has(b, key) && !(size--)) break;\n        }\n        result = !size;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    stack.pop();\n    return result;\n  }\n\n  // Perform a deep comparison to check if two objects are equal.\n  _.isEqual = function(a, b) {\n    return eq(a, b, []);\n  };\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  _.isEmpty = function(obj) {\n    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;\n    for (var key in obj) if (_.has(obj, key)) return false;\n    return true;\n  };\n\n  // Is a given value a DOM element?\n  _.isElement = function(obj) {\n    return !!(obj && obj.nodeType == 1);\n  };\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native Array.isArray\n  _.isArray = nativeIsArray || function(obj) {\n    return toString.call(obj) == '[object Array]';\n  };\n\n  // Is a given variable an object?\n  _.isObject = function(obj) {\n    return obj === Object(obj);\n  };\n\n  // Is a given variable an arguments object?\n  _.isArguments = function(obj) {\n    return toString.call(obj) == '[object Arguments]';\n  };\n  if (!_.isArguments(arguments)) {\n    _.isArguments = function(obj) {\n      return !!(obj && _.has(obj, 'callee'));\n    };\n  }\n\n  // Is a given value a function?\n  _.isFunction = function(obj) {\n    return toString.call(obj) == '[object Function]';\n  };\n\n  // Is a given value a string?\n  _.isString = function(obj) {\n    return toString.call(obj) == '[object String]';\n  };\n\n  // Is a given value a number?\n  _.isNumber = function(obj) {\n    return toString.call(obj) == '[object Number]';\n  };\n\n  // Is the given value `NaN`?\n  _.isNaN = function(obj) {\n    // `NaN` is the only value for which `===` is not reflexive.\n    return obj !== obj;\n  };\n\n  // Is a given value a boolean?\n  _.isBoolean = function(obj) {\n    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';\n  };\n\n  // Is a given value a date?\n  _.isDate = function(obj) {\n    return toString.call(obj) == '[object Date]';\n  };\n\n  // Is the given value a regular expression?\n  _.isRegExp = function(obj) {\n    return toString.call(obj) == '[object RegExp]';\n  };\n\n  // Is a given value equal to null?\n  _.isNull = function(obj) {\n    return obj === null;\n  };\n\n  // Is a given variable undefined?\n  _.isUndefined = function(obj) {\n    return obj === void 0;\n  };\n\n  // Has own property?\n  _.has = function(obj, key) {\n    return hasOwnProperty.call(obj, key);\n  };\n\n  // Utility Functions\n  // -----------------\n\n  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\n  // previous owner. Returns a reference to the Underscore object.\n  _.noConflict = function() {\n    root._ = previousUnderscore;\n    return this;\n  };\n\n  // Keep the identity function around for default iterators.\n  _.identity = function(value) {\n    return value;\n  };\n\n  // Run a function **n** times.\n  _.times = function (n, iterator, context) {\n    for (var i = 0; i < n; i++) iterator.call(context, i);\n  };\n\n  // Escape a string for HTML interpolation.\n  _.escape = function(string) {\n    return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\\//g,'&#x2F;');\n  };\n\n  // Add your own custom functions to the Underscore object, ensuring that\n  // they're correctly added to the OOP wrapper as well.\n  _.mixin = function(obj) {\n    each(_.functions(obj), function(name){\n      addToWrapper(name, _[name] = obj[name]);\n    });\n  };\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  _.uniqueId = function(prefix) {\n    var id = idCounter++;\n    return prefix ? prefix + id : id;\n  };\n\n  // By default, Underscore uses ERB-style template delimiters, change the\n  // following template settings to use alternative delimiters.\n  _.templateSettings = {\n    evaluate    : /<%([\\s\\S]+?)%>/g,\n    interpolate : /<%=([\\s\\S]+?)%>/g,\n    escape      : /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /.^/;\n\n  // Within an interpolation, evaluation, or escaping, remove HTML escaping\n  // that had been previously added.\n  var unescape = function(code) {\n    return code.replace(/\\\\\\\\/g, '\\\\').replace(/\\\\'/g, \"'\");\n  };\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  _.template = function(str, data) {\n    var c  = _.templateSettings;\n    var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +\n      'with(obj||{}){__p.push(\\'' +\n      str.replace(/\\\\/g, '\\\\\\\\')\n         .replace(/'/g, \"\\\\'\")\n         .replace(c.escape || noMatch, function(match, code) {\n           return \"',_.escape(\" + unescape(code) + \"),'\";\n         })\n         .replace(c.interpolate || noMatch, function(match, code) {\n           return \"',\" + unescape(code) + \",'\";\n         })\n         .replace(c.evaluate || noMatch, function(match, code) {\n           return \"');\" + unescape(code).replace(/[\\r\\n\\t]/g, ' ') + \";__p.push('\";\n         })\n         .replace(/\\r/g, '\\\\r')\n         .replace(/\\n/g, '\\\\n')\n         .replace(/\\t/g, '\\\\t')\n         + \"');}return __p.join('');\";\n    var func = new Function('obj', '_', tmpl);\n    if (data) return func(data, _);\n    return function(data) {\n      return func.call(this, data, _);\n    };\n  };\n\n  // Add a \"chain\" function, which will delegate to the wrapper.\n  _.chain = function(obj) {\n    return _(obj).chain();\n  };\n\n  // The OOP Wrapper\n  // ---------------\n\n  // If Underscore is called as a function, it returns a wrapped object that\n  // can be used OO-style. This wrapper holds altered versions of all the\n  // underscore functions. Wrapped objects may be chained.\n  var wrapper = function(obj) { this._wrapped = obj; };\n\n  // Expose `wrapper.prototype` as `_.prototype`\n  _.prototype = wrapper.prototype;\n\n  // Helper function to continue chaining intermediate results.\n  var result = function(obj, chain) {\n    return chain ? _(obj).chain() : obj;\n  };\n\n  // A method to easily add functions to the OOP wrapper.\n  var addToWrapper = function(name, func) {\n    wrapper.prototype[name] = function() {\n      var args = slice.call(arguments);\n      unshift.call(args, this._wrapped);\n      return result(func.apply(_, args), this._chain);\n    };\n  };\n\n  // Add all of the Underscore functions to the wrapper object.\n  _.mixin(_);\n\n  // Add all mutator Array functions to the wrapper.\n  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    wrapper.prototype[name] = function() {\n      var wrapped = this._wrapped;\n      method.apply(wrapped, arguments);\n      var length = wrapped.length;\n      if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];\n      return result(wrapped, this._chain);\n    };\n  });\n\n  // Add all accessor Array functions to the wrapper.\n  each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    wrapper.prototype[name] = function() {\n      return result(method.apply(this._wrapped, arguments), this._chain);\n    };\n  });\n\n  // Start chaining a wrapped Underscore object.\n  wrapper.prototype.chain = function() {\n    this._chain = true;\n    return this;\n  };\n\n  // Extracts the result from a wrapped and chained object.\n  wrapper.prototype.value = function() {\n    return this._wrapped;\n  };\n\n}).call(this);\n"
  },
  {
    "path": "docs/sphinx/_build/_static/underscore.js",
    "content": "// Underscore.js 1.3.1\n// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.\n// Underscore is freely distributable under the MIT license.\n// Portions of Underscore are inspired or borrowed from Prototype,\n// Oliver Steele's Functional, and John Resig's Micro-Templating.\n// For all details and documentation:\n// http://documentcloud.github.com/underscore\n(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case \"[object String]\":return a==String(c);case \"[object Number]\":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case \"[object Date]\":case \"[object Boolean]\":return+a==+c;case \"[object RegExp]\":return a.source==\nc.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!=\"object\"||typeof c!=\"object\")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e==\"[object Array]\"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if(\"constructor\"in a!=\"constructor\"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,\nh)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!==\"undefined\"){if(typeof module!==\"undefined\"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION=\"1.3.1\";var j=b.each=\nb.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==\nnull&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError(\"Reduce of empty array with no initial value\");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=\nfunction(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=\ne&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=\nfunction(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});\nreturn e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),\"value\")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,\nc,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=\nb.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);\nreturn e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,\"length\")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,\"\"+e);return d};b.indexOf=function(a,c,\nd){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};\nvar F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,\nc){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:\na.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};\nb.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError(\"Invalid object\");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,\n1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)==\"[object Array]\"};b.isObject=function(a){return a===Object(a)};\nb.isArguments=function(a){return l.call(a)==\"[object Arguments]\"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,\"callee\"))};b.isFunction=function(a){return l.call(a)==\"[object Function]\"};b.isString=function(a){return l.call(a)==\"[object String]\"};b.isNumber=function(a){return l.call(a)==\"[object Number]\"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)==\"[object Boolean]\"};b.isDate=function(a){return l.call(a)==\"[object Date]\"};\nb.isRegExp=function(a){return l.call(a)==\"[object RegExp]\"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(\"\"+a).replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\").replace(/'/g,\"&#x27;\").replace(/\\//g,\"&#x2F;\")};b.mixin=function(a){j(b.functions(a),\nfunction(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\\s\\S]+?)%>/g,interpolate:/<%=([\\s\\S]+?)%>/g,escape:/<%-([\\s\\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\\\\\/g,\"\\\\\").replace(/\\\\'/g,\"'\")};b.template=function(a,c){var d=b.templateSettings,d=\"var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('\"+a.replace(/\\\\/g,\"\\\\\\\\\").replace(/'/g,\"\\\\'\").replace(d.escape||t,function(a,b){return\"',_.escape(\"+\nu(b)+\"),'\"}).replace(d.interpolate||t,function(a,b){return\"',\"+u(b)+\",'\"}).replace(d.evaluate||t,function(a,b){return\"');\"+u(b).replace(/[\\r\\n\\t]/g,\" \")+\";__p.push('\"}).replace(/\\r/g,\"\\\\r\").replace(/\\n/g,\"\\\\n\").replace(/\\t/g,\"\\\\t\")+\"');}return __p.join('');\",e=new Function(\"obj\",\"_\",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=\nfunction(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j(\"pop,push,reverse,shift,sort,splice,unshift\".split(\",\"),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a==\"shift\"||a==\"splice\")&&e===0&&delete d[0];return v(d,this._chain)}});j([\"concat\",\"join\",\"slice\"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=\ntrue;return this};m.prototype.value=function(){return this._wrapped}}).call(this);\n"
  },
  {
    "path": "docs/sphinx/_build/_static/websupport.js",
    "content": "/*\n * websupport.js\n * ~~~~~~~~~~~~~\n *\n * sphinx.websupport utilities for all documentation.\n *\n * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n(function($) {\n  $.fn.autogrow = function() {\n    return this.each(function() {\n    var textarea = this;\n\n    $.fn.autogrow.resize(textarea);\n\n    $(textarea)\n      .focus(function() {\n        textarea.interval = setInterval(function() {\n          $.fn.autogrow.resize(textarea);\n        }, 500);\n      })\n      .blur(function() {\n        clearInterval(textarea.interval);\n      });\n    });\n  };\n\n  $.fn.autogrow.resize = function(textarea) {\n    var lineHeight = parseInt($(textarea).css('line-height'), 10);\n    var lines = textarea.value.split('\\n');\n    var columns = textarea.cols;\n    var lineCount = 0;\n    $.each(lines, function() {\n      lineCount += Math.ceil(this.length / columns) || 1;\n    });\n    var height = lineHeight * (lineCount + 1);\n    $(textarea).css('height', height);\n  };\n})(jQuery);\n\n(function($) {\n  var comp, by;\n\n  function init() {\n    initEvents();\n    initComparator();\n  }\n\n  function initEvents() {\n    $(document).on(\"click\", 'a.comment-close', function(event) {\n      event.preventDefault();\n      hide($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.vote', function(event) {\n      event.preventDefault();\n      handleVote($(this));\n    });\n    $(document).on(\"click\", 'a.reply', function(event) {\n      event.preventDefault();\n      openReply($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.close-reply', function(event) {\n      event.preventDefault();\n      closeReply($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.sort-option', function(event) {\n      event.preventDefault();\n      handleReSort($(this));\n    });\n    $(document).on(\"click\", 'a.show-proposal', function(event) {\n      event.preventDefault();\n      showProposal($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.hide-proposal', function(event) {\n      event.preventDefault();\n      hideProposal($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.show-propose-change', function(event) {\n      event.preventDefault();\n      showProposeChange($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.hide-propose-change', function(event) {\n      event.preventDefault();\n      hideProposeChange($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.accept-comment', function(event) {\n      event.preventDefault();\n      acceptComment($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.delete-comment', function(event) {\n      event.preventDefault();\n      deleteComment($(this).attr('id').substring(2));\n    });\n    $(document).on(\"click\", 'a.comment-markup', function(event) {\n      event.preventDefault();\n      toggleCommentMarkupBox($(this).attr('id').substring(2));\n    });\n  }\n\n  /**\n   * Set comp, which is a comparator function used for sorting and\n   * inserting comments into the list.\n   */\n  function setComparator() {\n    // If the first three letters are \"asc\", sort in ascending order\n    // and remove the prefix.\n    if (by.substring(0,3) == 'asc') {\n      var i = by.substring(3);\n      comp = function(a, b) { return a[i] - b[i]; };\n    } else {\n      // Otherwise sort in descending order.\n      comp = function(a, b) { return b[by] - a[by]; };\n    }\n\n    // Reset link styles and format the selected sort option.\n    $('a.sel').attr('href', '#').removeClass('sel');\n    $('a.by' + by).removeAttr('href').addClass('sel');\n  }\n\n  /**\n   * Create a comp function. If the user has preferences stored in\n   * the sortBy cookie, use those, otherwise use the default.\n   */\n  function initComparator() {\n    by = 'rating'; // Default to sort by rating.\n    // If the sortBy cookie is set, use that instead.\n    if (document.cookie.length > 0) {\n      var start = document.cookie.indexOf('sortBy=');\n      if (start != -1) {\n        start = start + 7;\n        var end = document.cookie.indexOf(\";\", start);\n        if (end == -1) {\n          end = document.cookie.length;\n          by = unescape(document.cookie.substring(start, end));\n        }\n      }\n    }\n    setComparator();\n  }\n\n  /**\n   * Show a comment div.\n   */\n  function show(id) {\n    $('#ao' + id).hide();\n    $('#ah' + id).show();\n    var context = $.extend({id: id}, opts);\n    var popup = $(renderTemplate(popupTemplate, context)).hide();\n    popup.find('textarea[name=\"proposal\"]').hide();\n    popup.find('a.by' + by).addClass('sel');\n    var form = popup.find('#cf' + id);\n    form.submit(function(event) {\n      event.preventDefault();\n      addComment(form);\n    });\n    $('#s' + id).after(popup);\n    popup.slideDown('fast', function() {\n      getComments(id);\n    });\n  }\n\n  /**\n   * Hide a comment div.\n   */\n  function hide(id) {\n    $('#ah' + id).hide();\n    $('#ao' + id).show();\n    var div = $('#sc' + id);\n    div.slideUp('fast', function() {\n      div.remove();\n    });\n  }\n\n  /**\n   * Perform an ajax request to get comments for a node\n   * and insert the comments into the comments tree.\n   */\n  function getComments(id) {\n    $.ajax({\n     type: 'GET',\n     url: opts.getCommentsURL,\n     data: {node: id},\n     success: function(data, textStatus, request) {\n       var ul = $('#cl' + id);\n       var speed = 100;\n       $('#cf' + id)\n         .find('textarea[name=\"proposal\"]')\n         .data('source', data.source);\n\n       if (data.comments.length === 0) {\n         ul.html('<li>No comments yet.</li>');\n         ul.data('empty', true);\n       } else {\n         // If there are comments, sort them and put them in the list.\n         var comments = sortComments(data.comments);\n         speed = data.comments.length * 100;\n         appendComments(comments, ul);\n         ul.data('empty', false);\n       }\n       $('#cn' + id).slideUp(speed + 200);\n       ul.slideDown(speed);\n     },\n     error: function(request, textStatus, error) {\n       showError('Oops, there was a problem retrieving the comments.');\n     },\n     dataType: 'json'\n    });\n  }\n\n  /**\n   * Add a comment via ajax and insert the comment into the comment tree.\n   */\n  function addComment(form) {\n    var node_id = form.find('input[name=\"node\"]').val();\n    var parent_id = form.find('input[name=\"parent\"]').val();\n    var text = form.find('textarea[name=\"comment\"]').val();\n    var proposal = form.find('textarea[name=\"proposal\"]').val();\n\n    if (text == '') {\n      showError('Please enter a comment.');\n      return;\n    }\n\n    // Disable the form that is being submitted.\n    form.find('textarea,input').attr('disabled', 'disabled');\n\n    // Send the comment to the server.\n    $.ajax({\n      type: \"POST\",\n      url: opts.addCommentURL,\n      dataType: 'json',\n      data: {\n        node: node_id,\n        parent: parent_id,\n        text: text,\n        proposal: proposal\n      },\n      success: function(data, textStatus, error) {\n        // Reset the form.\n        if (node_id) {\n          hideProposeChange(node_id);\n        }\n        form.find('textarea')\n          .val('')\n          .add(form.find('input'))\n          .removeAttr('disabled');\n\tvar ul = $('#cl' + (node_id || parent_id));\n        if (ul.data('empty')) {\n          $(ul).empty();\n          ul.data('empty', false);\n        }\n        insertComment(data.comment);\n        var ao = $('#ao' + node_id);\n        ao.find('img').attr({'src': opts.commentBrightImage});\n        if (node_id) {\n          // if this was a \"root\" comment, remove the commenting box\n          // (the user can get it back by reopening the comment popup)\n          $('#ca' + node_id).slideUp();\n        }\n      },\n      error: function(request, textStatus, error) {\n        form.find('textarea,input').removeAttr('disabled');\n        showError('Oops, there was a problem adding the comment.');\n      }\n    });\n  }\n\n  /**\n   * Recursively append comments to the main comment list and children\n   * lists, creating the comment tree.\n   */\n  function appendComments(comments, ul) {\n    $.each(comments, function() {\n      var div = createCommentDiv(this);\n      ul.append($(document.createElement('li')).html(div));\n      appendComments(this.children, div.find('ul.comment-children'));\n      // To avoid stagnating data, don't store the comments children in data.\n      this.children = null;\n      div.data('comment', this);\n    });\n  }\n\n  /**\n   * After adding a new comment, it must be inserted in the correct\n   * location in the comment tree.\n   */\n  function insertComment(comment) {\n    var div = createCommentDiv(comment);\n\n    // To avoid stagnating data, don't store the comments children in data.\n    comment.children = null;\n    div.data('comment', comment);\n\n    var ul = $('#cl' + (comment.node || comment.parent));\n    var siblings = getChildren(ul);\n\n    var li = $(document.createElement('li'));\n    li.hide();\n\n    // Determine where in the parents children list to insert this comment.\n    for(i=0; i < siblings.length; i++) {\n      if (comp(comment, siblings[i]) <= 0) {\n        $('#cd' + siblings[i].id)\n          .parent()\n          .before(li.html(div));\n        li.slideDown('fast');\n        return;\n      }\n    }\n\n    // If we get here, this comment rates lower than all the others,\n    // or it is the only comment in the list.\n    ul.append(li.html(div));\n    li.slideDown('fast');\n  }\n\n  function acceptComment(id) {\n    $.ajax({\n      type: 'POST',\n      url: opts.acceptCommentURL,\n      data: {id: id},\n      success: function(data, textStatus, request) {\n        $('#cm' + id).fadeOut('fast');\n        $('#cd' + id).removeClass('moderate');\n      },\n      error: function(request, textStatus, error) {\n        showError('Oops, there was a problem accepting the comment.');\n      }\n    });\n  }\n\n  function deleteComment(id) {\n    $.ajax({\n      type: 'POST',\n      url: opts.deleteCommentURL,\n      data: {id: id},\n      success: function(data, textStatus, request) {\n        var div = $('#cd' + id);\n        if (data == 'delete') {\n          // Moderator mode: remove the comment and all children immediately\n          div.slideUp('fast', function() {\n            div.remove();\n          });\n          return;\n        }\n        // User mode: only mark the comment as deleted\n        div\n          .find('span.user-id:first')\n          .text('[deleted]').end()\n          .find('div.comment-text:first')\n          .text('[deleted]').end()\n          .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +\n                ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)\n          .remove();\n        var comment = div.data('comment');\n        comment.username = '[deleted]';\n        comment.text = '[deleted]';\n        div.data('comment', comment);\n      },\n      error: function(request, textStatus, error) {\n        showError('Oops, there was a problem deleting the comment.');\n      }\n    });\n  }\n\n  function showProposal(id) {\n    $('#sp' + id).hide();\n    $('#hp' + id).show();\n    $('#pr' + id).slideDown('fast');\n  }\n\n  function hideProposal(id) {\n    $('#hp' + id).hide();\n    $('#sp' + id).show();\n    $('#pr' + id).slideUp('fast');\n  }\n\n  function showProposeChange(id) {\n    $('#pc' + id).hide();\n    $('#hc' + id).show();\n    var textarea = $('#pt' + id);\n    textarea.val(textarea.data('source'));\n    $.fn.autogrow.resize(textarea[0]);\n    textarea.slideDown('fast');\n  }\n\n  function hideProposeChange(id) {\n    $('#hc' + id).hide();\n    $('#pc' + id).show();\n    var textarea = $('#pt' + id);\n    textarea.val('').removeAttr('disabled');\n    textarea.slideUp('fast');\n  }\n\n  function toggleCommentMarkupBox(id) {\n    $('#mb' + id).toggle();\n  }\n\n  /** Handle when the user clicks on a sort by link. */\n  function handleReSort(link) {\n    var classes = link.attr('class').split(/\\s+/);\n    for (var i=0; i<classes.length; i++) {\n      if (classes[i] != 'sort-option') {\n\tby = classes[i].substring(2);\n      }\n    }\n    setComparator();\n    // Save/update the sortBy cookie.\n    var expiration = new Date();\n    expiration.setDate(expiration.getDate() + 365);\n    document.cookie= 'sortBy=' + escape(by) +\n                     ';expires=' + expiration.toUTCString();\n    $('ul.comment-ul').each(function(index, ul) {\n      var comments = getChildren($(ul), true);\n      comments = sortComments(comments);\n      appendComments(comments, $(ul).empty());\n    });\n  }\n\n  /**\n   * Function to process a vote when a user clicks an arrow.\n   */\n  function handleVote(link) {\n    if (!opts.voting) {\n      showError(\"You'll need to login to vote.\");\n      return;\n    }\n\n    var id = link.attr('id');\n    if (!id) {\n      // Didn't click on one of the voting arrows.\n      return;\n    }\n    // If it is an unvote, the new vote value is 0,\n    // Otherwise it's 1 for an upvote, or -1 for a downvote.\n    var value = 0;\n    if (id.charAt(1) != 'u') {\n      value = id.charAt(0) == 'u' ? 1 : -1;\n    }\n    // The data to be sent to the server.\n    var d = {\n      comment_id: id.substring(2),\n      value: value\n    };\n\n    // Swap the vote and unvote links.\n    link.hide();\n    $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)\n      .show();\n\n    // The div the comment is displayed in.\n    var div = $('div#cd' + d.comment_id);\n    var data = div.data('comment');\n\n    // If this is not an unvote, and the other vote arrow has\n    // already been pressed, unpress it.\n    if ((d.value !== 0) && (data.vote === d.value * -1)) {\n      $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();\n      $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();\n    }\n\n    // Update the comments rating in the local data.\n    data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);\n    data.vote = d.value;\n    div.data('comment', data);\n\n    // Change the rating text.\n    div.find('.rating:first')\n      .text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));\n\n    // Send the vote information to the server.\n    $.ajax({\n      type: \"POST\",\n      url: opts.processVoteURL,\n      data: d,\n      error: function(request, textStatus, error) {\n        showError('Oops, there was a problem casting that vote.');\n      }\n    });\n  }\n\n  /**\n   * Open a reply form used to reply to an existing comment.\n   */\n  function openReply(id) {\n    // Swap out the reply link for the hide link\n    $('#rl' + id).hide();\n    $('#cr' + id).show();\n\n    // Add the reply li to the children ul.\n    var div = $(renderTemplate(replyTemplate, {id: id})).hide();\n    $('#cl' + id)\n      .prepend(div)\n      // Setup the submit handler for the reply form.\n      .find('#rf' + id)\n      .submit(function(event) {\n        event.preventDefault();\n        addComment($('#rf' + id));\n        closeReply(id);\n      })\n      .find('input[type=button]')\n      .click(function() {\n        closeReply(id);\n      });\n    div.slideDown('fast', function() {\n      $('#rf' + id).find('textarea').focus();\n    });\n  }\n\n  /**\n   * Close the reply form opened with openReply.\n   */\n  function closeReply(id) {\n    // Remove the reply div from the DOM.\n    $('#rd' + id).slideUp('fast', function() {\n      $(this).remove();\n    });\n\n    // Swap out the hide link for the reply link\n    $('#cr' + id).hide();\n    $('#rl' + id).show();\n  }\n\n  /**\n   * Recursively sort a tree of comments using the comp comparator.\n   */\n  function sortComments(comments) {\n    comments.sort(comp);\n    $.each(comments, function() {\n      this.children = sortComments(this.children);\n    });\n    return comments;\n  }\n\n  /**\n   * Get the children comments from a ul. If recursive is true,\n   * recursively include childrens' children.\n   */\n  function getChildren(ul, recursive) {\n    var children = [];\n    ul.children().children(\"[id^='cd']\")\n      .each(function() {\n        var comment = $(this).data('comment');\n        if (recursive)\n          comment.children = getChildren($(this).find('#cl' + comment.id), true);\n        children.push(comment);\n      });\n    return children;\n  }\n\n  /** Create a div to display a comment in. */\n  function createCommentDiv(comment) {\n    if (!comment.displayed && !opts.moderator) {\n      return $('<div class=\"moderate\">Thank you!  Your comment will show up '\n               + 'once it is has been approved by a moderator.</div>');\n    }\n    // Prettify the comment rating.\n    comment.pretty_rating = comment.rating + ' point' +\n      (comment.rating == 1 ? '' : 's');\n    // Make a class (for displaying not yet moderated comments differently)\n    comment.css_class = comment.displayed ? '' : ' moderate';\n    // Create a div for this comment.\n    var context = $.extend({}, opts, comment);\n    var div = $(renderTemplate(commentTemplate, context));\n\n    // If the user has voted on this comment, highlight the correct arrow.\n    if (comment.vote) {\n      var direction = (comment.vote == 1) ? 'u' : 'd';\n      div.find('#' + direction + 'v' + comment.id).hide();\n      div.find('#' + direction + 'u' + comment.id).show();\n    }\n\n    if (opts.moderator || comment.text != '[deleted]') {\n      div.find('a.reply').show();\n      if (comment.proposal_diff)\n        div.find('#sp' + comment.id).show();\n      if (opts.moderator && !comment.displayed)\n        div.find('#cm' + comment.id).show();\n      if (opts.moderator || (opts.username == comment.username))\n        div.find('#dc' + comment.id).show();\n    }\n    return div;\n  }\n\n  /**\n   * A simple template renderer. Placeholders such as <%id%> are replaced\n   * by context['id'] with items being escaped. Placeholders such as <#id#>\n   * are not escaped.\n   */\n  function renderTemplate(template, context) {\n    var esc = $(document.createElement('div'));\n\n    function handle(ph, escape) {\n      var cur = context;\n      $.each(ph.split('.'), function() {\n        cur = cur[this];\n      });\n      return escape ? esc.text(cur || \"\").html() : cur;\n    }\n\n    return template.replace(/<([%#])([\\w\\.]*)\\1>/g, function() {\n      return handle(arguments[2], arguments[1] == '%' ? true : false);\n    });\n  }\n\n  /** Flash an error message briefly. */\n  function showError(message) {\n    $(document.createElement('div')).attr({'class': 'popup-error'})\n      .append($(document.createElement('div'))\n               .attr({'class': 'error-message'}).text(message))\n      .appendTo('body')\n      .fadeIn(\"slow\")\n      .delay(2000)\n      .fadeOut(\"slow\");\n  }\n\n  /** Add a link the user uses to open the comments popup. */\n  $.fn.comment = function() {\n    return this.each(function() {\n      var id = $(this).attr('id').substring(1);\n      var count = COMMENT_METADATA[id];\n      var title = count + ' comment' + (count == 1 ? '' : 's');\n      var image = count > 0 ? opts.commentBrightImage : opts.commentImage;\n      var addcls = count == 0 ? ' nocomment' : '';\n      $(this)\n        .append(\n          $(document.createElement('a')).attr({\n            href: '#',\n            'class': 'sphinx-comment-open' + addcls,\n            id: 'ao' + id\n          })\n            .append($(document.createElement('img')).attr({\n              src: image,\n              alt: 'comment',\n              title: title\n            }))\n            .click(function(event) {\n              event.preventDefault();\n              show($(this).attr('id').substring(2));\n            })\n        )\n        .append(\n          $(document.createElement('a')).attr({\n            href: '#',\n            'class': 'sphinx-comment-close hidden',\n            id: 'ah' + id\n          })\n            .append($(document.createElement('img')).attr({\n              src: opts.closeCommentImage,\n              alt: 'close',\n              title: 'close'\n            }))\n            .click(function(event) {\n              event.preventDefault();\n              hide($(this).attr('id').substring(2));\n            })\n        );\n    });\n  };\n\n  var opts = {\n    processVoteURL: '/_process_vote',\n    addCommentURL: '/_add_comment',\n    getCommentsURL: '/_get_comments',\n    acceptCommentURL: '/_accept_comment',\n    deleteCommentURL: '/_delete_comment',\n    commentImage: '/static/_static/comment.png',\n    closeCommentImage: '/static/_static/comment-close.png',\n    loadingImage: '/static/_static/ajax-loader.gif',\n    commentBrightImage: '/static/_static/comment-bright.png',\n    upArrow: '/static/_static/up.png',\n    downArrow: '/static/_static/down.png',\n    upArrowPressed: '/static/_static/up-pressed.png',\n    downArrowPressed: '/static/_static/down-pressed.png',\n    voting: false,\n    moderator: false\n  };\n\n  if (typeof COMMENT_OPTIONS != \"undefined\") {\n    opts = jQuery.extend(opts, COMMENT_OPTIONS);\n  }\n\n  var popupTemplate = '\\\n    <div class=\"sphinx-comments\" id=\"sc<%id%>\">\\\n      <p class=\"sort-options\">\\\n        Sort by:\\\n        <a href=\"#\" class=\"sort-option byrating\">best rated</a>\\\n        <a href=\"#\" class=\"sort-option byascage\">newest</a>\\\n        <a href=\"#\" class=\"sort-option byage\">oldest</a>\\\n      </p>\\\n      <div class=\"comment-header\">Comments</div>\\\n      <div class=\"comment-loading\" id=\"cn<%id%>\">\\\n        loading comments... <img src=\"<%loadingImage%>\" alt=\"\" /></div>\\\n      <ul id=\"cl<%id%>\" class=\"comment-ul\"></ul>\\\n      <div id=\"ca<%id%>\">\\\n      <p class=\"add-a-comment\">Add a comment\\\n        (<a href=\"#\" class=\"comment-markup\" id=\"ab<%id%>\">markup</a>):</p>\\\n      <div class=\"comment-markup-box\" id=\"mb<%id%>\">\\\n        reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \\\n        <code>``code``</code>, \\\n        code blocks: <code>::</code> and an indented block after blank line</div>\\\n      <form method=\"post\" id=\"cf<%id%>\" class=\"comment-form\" action=\"\">\\\n        <textarea name=\"comment\" cols=\"80\"></textarea>\\\n        <p class=\"propose-button\">\\\n          <a href=\"#\" id=\"pc<%id%>\" class=\"show-propose-change\">\\\n            Propose a change &#9657;\\\n          </a>\\\n          <a href=\"#\" id=\"hc<%id%>\" class=\"hide-propose-change\">\\\n            Propose a change &#9663;\\\n          </a>\\\n        </p>\\\n        <textarea name=\"proposal\" id=\"pt<%id%>\" cols=\"80\"\\\n                  spellcheck=\"false\"></textarea>\\\n        <input type=\"submit\" value=\"Add comment\" />\\\n        <input type=\"hidden\" name=\"node\" value=\"<%id%>\" />\\\n        <input type=\"hidden\" name=\"parent\" value=\"\" />\\\n      </form>\\\n      </div>\\\n    </div>';\n\n  var commentTemplate = '\\\n    <div id=\"cd<%id%>\" class=\"sphinx-comment<%css_class%>\">\\\n      <div class=\"vote\">\\\n        <div class=\"arrow\">\\\n          <a href=\"#\" id=\"uv<%id%>\" class=\"vote\" title=\"vote up\">\\\n            <img src=\"<%upArrow%>\" />\\\n          </a>\\\n          <a href=\"#\" id=\"uu<%id%>\" class=\"un vote\" title=\"vote up\">\\\n            <img src=\"<%upArrowPressed%>\" />\\\n          </a>\\\n        </div>\\\n        <div class=\"arrow\">\\\n          <a href=\"#\" id=\"dv<%id%>\" class=\"vote\" title=\"vote down\">\\\n            <img src=\"<%downArrow%>\" id=\"da<%id%>\" />\\\n          </a>\\\n          <a href=\"#\" id=\"du<%id%>\" class=\"un vote\" title=\"vote down\">\\\n            <img src=\"<%downArrowPressed%>\" />\\\n          </a>\\\n        </div>\\\n      </div>\\\n      <div class=\"comment-content\">\\\n        <p class=\"tagline comment\">\\\n          <span class=\"user-id\"><%username%></span>\\\n          <span class=\"rating\"><%pretty_rating%></span>\\\n          <span class=\"delta\"><%time.delta%></span>\\\n        </p>\\\n        <div class=\"comment-text comment\"><#text#></div>\\\n        <p class=\"comment-opts comment\">\\\n          <a href=\"#\" class=\"reply hidden\" id=\"rl<%id%>\">reply &#9657;</a>\\\n          <a href=\"#\" class=\"close-reply\" id=\"cr<%id%>\">reply &#9663;</a>\\\n          <a href=\"#\" id=\"sp<%id%>\" class=\"show-proposal\">proposal &#9657;</a>\\\n          <a href=\"#\" id=\"hp<%id%>\" class=\"hide-proposal\">proposal &#9663;</a>\\\n          <a href=\"#\" id=\"dc<%id%>\" class=\"delete-comment hidden\">delete</a>\\\n          <span id=\"cm<%id%>\" class=\"moderation hidden\">\\\n            <a href=\"#\" id=\"ac<%id%>\" class=\"accept-comment\">accept</a>\\\n          </span>\\\n        </p>\\\n        <pre class=\"proposal\" id=\"pr<%id%>\">\\\n<#proposal_diff#>\\\n        </pre>\\\n          <ul class=\"comment-children\" id=\"cl<%id%>\"></ul>\\\n        </div>\\\n        <div class=\"clearleft\"></div>\\\n      </div>\\\n    </div>';\n\n  var replyTemplate = '\\\n    <li>\\\n      <div class=\"reply-div\" id=\"rd<%id%>\">\\\n        <form id=\"rf<%id%>\">\\\n          <textarea name=\"comment\" cols=\"80\"></textarea>\\\n          <input type=\"submit\" value=\"Add reply\" />\\\n          <input type=\"button\" value=\"Cancel\" />\\\n          <input type=\"hidden\" name=\"parent\" value=\"<%id%>\" />\\\n          <input type=\"hidden\" name=\"node\" value=\"\" />\\\n        </form>\\\n      </div>\\\n    </li>';\n\n  $(document).ready(function() {\n    init();\n  });\n})(jQuery);\n\n$(document).ready(function() {\n  // add comment anchors for all paragraphs that are commentable\n  $('.sphinx-has-comment').comment();\n\n  // highlight search words in search results\n  $(\"div.context\").each(function() {\n    var params = $.getQueryParameters();\n    var terms = (params.q) ? params.q[0].split(/\\s+/) : [];\n    var result = $(this);\n    $.each(terms, function() {\n      result.highlightText(this.toLowerCase(), 'highlighted');\n    });\n  });\n\n  // directly open comment window if requested\n  var anchor = document.location.hash;\n  if (anchor.substring(0, 9) == '#comment-') {\n    $('#ao' + anchor.substring(9)).click();\n    document.location.hash = '#s' + anchor.substring(9);\n  }\n});\n"
  },
  {
    "path": "docs/sphinx/_build/genindex.html",
    "content": "\n\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Index &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"#\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>Index</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n\n<h1 id=\"index\">Index</h1>\n\n<div class=\"genindex-jumpbox\">\n <a href=\"#_\"><strong>_</strong></a>\n | <a href=\"#A\"><strong>A</strong></a>\n | <a href=\"#B\"><strong>B</strong></a>\n | <a href=\"#C\"><strong>C</strong></a>\n | <a href=\"#D\"><strong>D</strong></a>\n | <a href=\"#E\"><strong>E</strong></a>\n | <a href=\"#F\"><strong>F</strong></a>\n | <a href=\"#G\"><strong>G</strong></a>\n | <a href=\"#H\"><strong>H</strong></a>\n | <a href=\"#I\"><strong>I</strong></a>\n | <a href=\"#L\"><strong>L</strong></a>\n | <a href=\"#M\"><strong>M</strong></a>\n | <a href=\"#N\"><strong>N</strong></a>\n | <a href=\"#O\"><strong>O</strong></a>\n | <a href=\"#P\"><strong>P</strong></a>\n | <a href=\"#R\"><strong>R</strong></a>\n | <a href=\"#S\"><strong>S</strong></a>\n | <a href=\"#T\"><strong>T</strong></a>\n | <a href=\"#U\"><strong>U</strong></a>\n | <a href=\"#V\"><strong>V</strong></a>\n | <a href=\"#W\"><strong>W</strong></a>\n | <a href=\"#X\"><strong>X</strong></a>\n | <a href=\"#Z\"><strong>Z</strong></a>\n \n</div>\n<h2 id=\"_\">_</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.__best\">__best (UCTB.train.EarlyStopping.EarlyStopping attribute)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.__best\">(UCTB.train.EarlyStopping.EarlyStoppingTTest attribute)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.__p\">__p (UCTB.train.EarlyStopping.EarlyStopping attribute)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.__p_value_threshold\">__p_value_threshold (UCTB.train.EarlyStopping.EarlyStoppingTTest attribute)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.__patience\">__patience (UCTB.train.EarlyStopping.EarlyStopping attribute)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.__record_list\">__record_list (UCTB.train.EarlyStopping.EarlyStopping attribute)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.__record_list\">(UCTB.train.EarlyStopping.EarlyStoppingTTest attribute)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.__test_length\">__test_length (UCTB.train.EarlyStopping.EarlyStoppingTTest attribute)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"A\">A</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL.add_ga_layer_matrix\">add_ga_layer_matrix() (UCTB.model_unit.GraphModelLayers.GAL static method)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GCL.add_gc_layer\">add_gc_layer() (UCTB.model_unit.GraphModelLayers.GCL static method)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GCL.add_multi_gc_layers\">add_multi_gc_layers() (UCTB.model_unit.GraphModelLayers.GCL static method)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL.add_residual_ga_layer\">add_residual_ga_layer() (UCTB.model_unit.GraphModelLayers.GAL static method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ARIMA.ARIMA.adf_test\">adf_test() (UCTB.model.ARIMA.ARIMA static method)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.adjacent_to_laplacian\">adjacent_to_laplacian() (UCTB.preprocess.GraphGenerator.GraphGenerator static method)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.AGCRN.AGCRN\">AGCRN (class in UCTB.model.AGCRN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.alias_draw\">alias_draw() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.alias_setup\">alias_setup() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.AM\">AM (UCTB.preprocess.GraphGenerator.GraphGenerator attribute)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ARIMA.ARIMA\">ARIMA (class in UCTB.model.ARIMA)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.ASTGCN_submodule\">ASTGCN_submodule (class in UCTB.model.ASTGCN)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL.attention_merge_weight\">attention_merge_weight() (UCTB.model_unit.GraphModelLayers.GAL static method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"B\">B</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel\">BaseModel (class in UCTB.model_unit.BaseModel)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.DCRNN.DCRNN.build\">build() (UCTB.model.DCRNN.DCRNN method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.model.html#UCTB.model.DeepST.DeepST.build\">(UCTB.model.DeepST.DeepST method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.GeoMAN.GeoMAN.build\">(UCTB.model.GeoMAN.GeoMAN method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.STMeta.STMeta.build\">(UCTB.model.STMeta.STMeta method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.ST_MGCN.ST_MGCN.build\">(UCTB.model.ST_MGCN.ST_MGCN method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.ST_ResNet.ST_ResNet.build\">(UCTB.model.ST_ResNet.ST_ResNet method)</a>\n</li>\n        <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.build\">(UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.build_model\">build_model() (in module UCTB.model.STGCN)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"C\">C</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell.call\">call() (UCTB.model_unit.DCRNN_CELL.DCGRUCell method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.cheb_conv\">cheb_conv (class in UCTB.model.ASTGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.cheb_conv_withSAt\">cheb_conv_withSAt (class in UCTB.model.ASTGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.cheb_poly_approx\">cheb_poly_approx() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.cheb_polynomial\">cheb_polynomial() (in module UCTB.model.ASTGCN)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.chooseNormalizer\">chooseNormalizer() (in module UCTB.preprocess.preprocessor)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.close\">close() (UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell.compute_output_shape\">compute_output_shape() (UCTB.model_unit.DCRNN_CELL.DCGRUCell method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.construct_adj\">construct_adj() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.correlation_adjacent\">correlation_adjacent() (UCTB.preprocess.GraphGenerator.GraphGenerator static method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"D\">D</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.daily_slots\">daily_slots (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.data\">data (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet\">DataSet (class in UCTB.dataset.dataset)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.dataset\">dataset (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell\">DCGRUCell (class in UCTB.model_unit.DCRNN_CELL)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.DCRNN.DCRNN\">DCRNN (class in UCTB.model.DCRNN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.DeepST.DeepST\">DeepST (class in UCTB.model.DeepST)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.distance_adjacent\">distance_adjacent() (UCTB.preprocess.GraphGenerator.GraphGenerator method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"E\">E</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping\">EarlyStopping (class in UCTB.train.EarlyStopping)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest\">EarlyStoppingTTest (class in UCTB.train.EarlyStopping)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.external_dim\">external_dim (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"F\">F</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.XGBoost.XGBoost.fit\">fit() (UCTB.model.XGBoost.XGBoost method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.fit\">(UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.ASTGCN_submodule.forward\">forward() (UCTB.model.ASTGCN.ASTGCN_submodule method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.Spatial_Attention_layer.forward\">(UCTB.model.ASTGCN.Spatial_Attention_layer method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.cheb_conv.forward\">(UCTB.model.ASTGCN.cheb_conv method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.cheb_conv_withSAt.forward\">(UCTB.model.ASTGCN.cheb_conv_withSAt method)</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.fully_con_layer\">fully_con_layer() (in module UCTB.model.STGCN)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"G\">G</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GAL\">GAL (class in UCTB.model_unit.GraphModelLayers)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.gatedFusion\">gatedFusion() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.GraphModelLayers.GCL\">GCL (class in UCTB.model_unit.GraphModelLayers)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.ST_RNN.GCLSTMCell\">GCLSTMCell (class in UCTB.model_unit.ST_RNN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.gcn_operation\">gcn_operation() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.gconv\">gconv() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.gen_batch\">gen_batch() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GeoMAN.GeoMAN\">GeoMAN (class in UCTB.model.GeoMAN)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.get_adjacency_matrix\">get_adjacency_matrix() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.get_batch\">get_batch() (UCTB.train.MiniBatchTrain.MiniBatchFeedDict method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain.get_batch\">(UCTB.train.MiniBatchTrain.MiniBatchTrain method)</a>\n</li>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.get_batch\">(UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData method)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ARIMA.ARIMA.get_order\">get_order() (UCTB.model.ARIMA.ARIMA method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.GMAN\">GMAN() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator\">GraphGenerator (class in UCTB.preprocess.GraphGenerator)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GraphWaveNet.gwnet\">gwnet (class in UCTB.model.GraphWaveNet)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"H\">H</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.haversine\">haversine() (UCTB.preprocess.GraphGenerator.GraphGenerator static method)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.HM.HM\">HM (class in UCTB.model.HM)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"I\">I</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.GeoMAN.input_transform\">input_transform() (in module UCTB.model.GeoMAN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.interaction_adjacent\">interaction_adjacent() (UCTB.preprocess.GraphGenerator.GraphGenerator static method)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.MaxMinNormalizer.inverse_transform\">inverse_transform() (UCTB.preprocess.preprocessor.MaxMinNormalizer method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.WhiteNormalizer.inverse_transform\">(UCTB.preprocess.preprocessor.WhiteNormalizer method)</a>\n</li>\n        <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.ZscoreNormalizer.inverse_transform\">(UCTB.preprocess.preprocessor.ZscoreNormalizer method)</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.time_utils.is_valid_date\">is_valid_date() (in module UCTB.preprocess.time_utils)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.time_utils.is_work_day_america\">is_work_day_america() (in module UCTB.preprocess.time_utils)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.time_utils.is_work_day_china\">is_work_day_china() (in module UCTB.preprocess.time_utils)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"L\">L</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.layer_norm\">layer_norm() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.GraphGenerator.LM\">LM (UCTB.preprocess.GraphGenerator.GraphGenerator attribute)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.load\">load() (UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.load_event_scalar\">load_event_scalar() (UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"M\">M</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.mae\">mae() (in module UCTB.evaluation.metric)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.make_concat\">make_concat() (UCTB.dataset.data_loader.NodeTrafficLoader method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.make_model\">make_model() (in module UCTB.model.ASTGCN)</a>\n</li>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.mape\">mape() (in module UCTB.evaluation.metric)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.MaxMinNormalizer\">MaxMinNormalizer (class in UCTB.preprocess.preprocessor)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.merge_data\">merge_data() (UCTB.dataset.dataset.DataSet method)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.MergeIndex\">MergeIndex (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.MergeWay\">MergeWay (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict\">MiniBatchFeedDict (class in UCTB.train.MiniBatchTrain)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain\">MiniBatchTrain (class in UCTB.train.MiniBatchTrain)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData\">MiniBatchTrainMultiData (class in UCTB.train.MiniBatchTrain)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.ST_MoveSample.move_sample\">move_sample() (UCTB.preprocess.preprocessor.ST_MoveSample method)</a>\n</li>\n      <li><a href=\"UCTB.utils.html#UCTB.utils.multi_threads.multiple_process\">multiple_process() (in module UCTB.utils.multi_threads)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"N\">N</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.node_monthly_interaction\">node_monthly_interaction (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.node_station_info\">node_station_info (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.node_traffic\">node_traffic (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader\">NodeTrafficLoader (class in UCTB.dataset.data_loader)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.Normalizer\">Normalizer (class in UCTB.preprocess.preprocessor)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"O\">O</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.output_layer\">output_layer() (in module UCTB.model.STGCN)</a>\n\n      <ul>\n        <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.output_layer\">(in module UCTB.model.STSGCN)</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell.output_size\">output_size (UCTB.model_unit.DCRNN_CELL.DCGRUCell attribute)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"P\">P</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.position_embedding\">position_embedding() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ARIMA.ARIMA.predict\">predict() (UCTB.model.ARIMA.ARIMA method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.model.html#UCTB.model.HM.HM.predict\">(UCTB.model.HM.HM method)</a>\n</li>\n        <li><a href=\"UCTB.model.html#UCTB.model.XGBoost.XGBoost.predict\">(UCTB.model.XGBoost.XGBoost method)</a>\n</li>\n        <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.predict\">(UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      </ul></li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"R\">R</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.restart\">restart() (UCTB.train.MiniBatchTrain.MiniBatchFeedDict method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain.restart\">(UCTB.train.MiniBatchTrain.MiniBatchTrain method)</a>\n</li>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.restart\">(UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData method)</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.rmse\">rmse() (in module UCTB.evaluation.metric)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"S\">S</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.save\">save() (UCTB.model_unit.BaseModel.BaseModel method)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.scaled_Laplacian_ASTGCN\">scaled_Laplacian_ASTGCN() (in module UCTB.preprocess.GraphGenerator)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.GraphGenerator.scaled_laplacian_STGCN\">scaled_laplacian_STGCN() (in module UCTB.preprocess.GraphGenerator)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchFeedDict.shuffle\">shuffle() (UCTB.train.MiniBatchTrain.MiniBatchFeedDict static method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrain.shuffle\">(UCTB.train.MiniBatchTrain.MiniBatchTrain static method)</a>\n</li>\n        <li><a href=\"UCTB.train.html#UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData.shuffle\">(UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData static method)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.smape\">smape() (in module UCTB.evaluation.metric)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ASTGCN.Spatial_Attention_layer\">Spatial_Attention_layer (class in UCTB.model.ASTGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.spatialAttention\">spatialAttention() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.spatio_conv_layer\">spatio_conv_layer() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.SplitData.split_data\">split_data() (UCTB.preprocess.preprocessor.SplitData static method)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.SplitData.split_feed_dict\">split_feed_dict() (UCTB.preprocess.preprocessor.SplitData static method)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GeoMAN.split_timesteps\">split_timesteps() (in module UCTB.model.GeoMAN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.SplitData\">SplitData (class in UCTB.preprocess.preprocessor)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.st_conv_block\">st_conv_block() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ST_MGCN.ST_MGCN\">ST_MGCN (class in UCTB.model.ST_MGCN)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.ST_MoveSample\">ST_MoveSample (class in UCTB.preprocess.preprocessor)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.ST_ResNet.ST_ResNet\">ST_ResNet (class in UCTB.model.ST_ResNet)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#UCTB.model_unit.DCRNN_CELL.DCGRUCell.state_size\">state_size (UCTB.model_unit.DCRNN_CELL.DCGRUCell attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.station_number\">station_number (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.STEmbedding\">STEmbedding() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.sthgcn_layer_individual\">sthgcn_layer_individual() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.sthgcn_layer_sharing\">sthgcn_layer_sharing() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STMeta.STMeta\">STMeta (class in UCTB.model.STMeta)</a>\n</li>\n      <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStopping.stop\">stop() (UCTB.train.EarlyStopping.EarlyStopping method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.train.html#UCTB.train.EarlyStopping.EarlyStoppingTTest.stop\">(UCTB.train.EarlyStopping.EarlyStoppingTTest method)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.stsgcl\">stsgcl() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.stsgcm\">stsgcm() (in module UCTB.model.STSGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.STSGCN.stsgcn\">stsgcn() (in module UCTB.model.STSGCN)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"T\">T</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.temporal_conv_layer\">temporal_conv_layer() (in module UCTB.model.STGCN)</a>\n</li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.temporalAttention\">temporalAttention() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.time_fitness\">time_fitness (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.dataset.DataSet.time_range\">time_range (UCTB.dataset.dataset.DataSet attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.train_closeness\">train_closeness (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#UCTB.dataset.data_loader.NodeTrafficLoader.train_y\">train_y (UCTB.dataset.data_loader.NodeTrafficLoader attribute)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.MaxMinNormalizer.transform\">transform() (UCTB.preprocess.preprocessor.MaxMinNormalizer method)</a>\n\n      <ul>\n        <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.WhiteNormalizer.transform\">(UCTB.preprocess.preprocessor.WhiteNormalizer method)</a>\n</li>\n        <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.ZscoreNormalizer.transform\">(UCTB.preprocess.preprocessor.ZscoreNormalizer method)</a>\n</li>\n      </ul></li>\n      <li><a href=\"UCTB.model.html#UCTB.model.GMAN.transformAttention\">transformAttention() (in module UCTB.model.GMAN)</a>\n</li>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.trunc_mae\">trunc_mae() (in module UCTB.evaluation.metric)</a>\n</li>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.trunc_rmse\">trunc_rmse() (in module UCTB.evaluation.metric)</a>\n</li>\n      <li><a href=\"UCTB.evaluation.html#UCTB.evaluation.metric.trunc_smape\">trunc_smape() (in module UCTB.evaluation.metric)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"U\">U</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.html#module-UCTB\">UCTB (module)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#module-UCTB.dataset.data_loader\">UCTB.dataset.data_loader (module)</a>\n</li>\n      <li><a href=\"UCTB.dataset.html#module-UCTB.dataset.dataset\">UCTB.dataset.dataset (module)</a>\n</li>\n      <li><a href=\"UCTB.evaluation.html#module-UCTB.evaluation.metric\">UCTB.evaluation.metric (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.AGCRN\">UCTB.model.AGCRN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.ARIMA\">UCTB.model.ARIMA (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.ASTGCN\">UCTB.model.ASTGCN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.DCRNN\">UCTB.model.DCRNN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.DeepST\">UCTB.model.DeepST (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.GeoMAN\">UCTB.model.GeoMAN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.GMAN\">UCTB.model.GMAN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.GraphWaveNet\">UCTB.model.GraphWaveNet (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.HM\">UCTB.model.HM (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.ST_MGCN\">UCTB.model.ST_MGCN (module)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.ST_ResNet\">UCTB.model.ST_ResNet (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.STGCN\">UCTB.model.STGCN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.STMeta\">UCTB.model.STMeta (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.STSGCN\">UCTB.model.STSGCN (module)</a>\n</li>\n      <li><a href=\"UCTB.model.html#module-UCTB.model.XGBoost\">UCTB.model.XGBoost (module)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#module-UCTB.model_unit.BaseModel\">UCTB.model_unit.BaseModel (module)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#module-UCTB.model_unit.DCRNN_CELL\">UCTB.model_unit.DCRNN_CELL (module)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#module-UCTB.model_unit.GraphModelLayers\">UCTB.model_unit.GraphModelLayers (module)</a>\n</li>\n      <li><a href=\"UCTB.model_unit.html#module-UCTB.model_unit.ST_RNN\">UCTB.model_unit.ST_RNN (module)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#module-UCTB.preprocess.GraphGenerator\">UCTB.preprocess.GraphGenerator (module)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#module-UCTB.preprocess.preprocessor\">UCTB.preprocess.preprocessor (module)</a>\n</li>\n      <li><a href=\"UCTB.preprocess.html#module-UCTB.preprocess.time_utils\">UCTB.preprocess.time_utils (module)</a>\n</li>\n      <li><a href=\"UCTB.train.html#module-UCTB.train.EarlyStopping\">UCTB.train.EarlyStopping (module)</a>\n</li>\n      <li><a href=\"UCTB.train.html#module-UCTB.train.MiniBatchTrain\">UCTB.train.MiniBatchTrain (module)</a>\n</li>\n      <li><a href=\"UCTB.utils.html#module-UCTB.utils.multi_threads\">UCTB.utils.multi_threads (module)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"V\">V</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.STGCN.variable_summaries\">variable_summaries() (in module UCTB.model.STGCN)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"W\">W</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.WhiteNormalizer\">WhiteNormalizer (class in UCTB.preprocess.preprocessor)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"X\">X</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.model.html#UCTB.model.XGBoost.XGBoost\">XGBoost (class in UCTB.model.XGBoost)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"Z\">Z</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"UCTB.preprocess.html#UCTB.preprocess.preprocessor.ZscoreNormalizer\">ZscoreNormalizer (class in UCTB.preprocess.preprocessor)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/index.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Welcome to UCTB’s documentation! &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"#\"/>\n        <link rel=\"next\" title=\"1. Introduction\" href=\"md_file/introduction.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"#\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"#\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"#\">Docs</a> &raquo;</li>\n        \n      <li>Welcome to UCTB’s documentation!</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/index.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"welcome-to-uctb-s-documentation\">\n<h1>Welcome to UCTB’s documentation!<a class=\"headerlink\" href=\"#welcome-to-uctb-s-documentation\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/introduction.html#urban-datasts\">1.1. Urban Datasts</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/introduction.html#predictive-tool\">1.2. Predictive Tool</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/introduction.html#visualization-tool\">1.3. Visualization Tool</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/installation.html#install-via-anaconda\">2.1. Install via Anaconda</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/installation.html#check-for-success\">2.2. Check for Success</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/installation.html#high-version-gpu-framework-support\">2.3. High version GPU Framework support</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/installation.html#q-a\">2.4. Q &amp; A</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#datasets-overview\">3.1. Datasets Overview</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#bike-datasets\">3.2. Bike Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#bus-datasets\">3.3. Bus Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#speed-datasets\">3.4. Speed Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#pedestrian-datasets\">3.5. Pedestrian Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#taxi-datasets\">3.6. Taxi Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#metro-datasets\">3.7. Metro Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#flow-speed-datasets\">3.8. Flow Speed Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#load-uctb-dataset\">3.9. Load UCTB Dataset</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#how-to-get-the-datasets-at-other-granularities\">3.10. How to get the datasets at other granularities?</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html#build-your-own-datasets\">3.11. Build your own datasets</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html#currently-supported-models\">4.1. Currently Supported Models</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html#quick-start\">4.2. Quick Start</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html#tutorial\">4.3. Tutorial</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html#advanced-features\">4.4. Advanced Features</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html#quick-start\">5.1. Quick Start</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html#contribute-to-our-project\">5.2. Contribute to our project.</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.dataset.html\">6.1. UCTB.dataset package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.preprocess.html\">6.2. UCTB.preprocess package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model_unit.html\">6.3. UCTB.model_unit package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.model.html\">6.4. UCTB.model package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.evaluation.html\">6.5. UCTB.evaluation package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.train.html\">6.6. UCTB.train package</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.utils.html\">6.7. UCTB.utils package</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/all_results.html#datasets\">7.1. Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/all_results.html#results\">7.2. Results</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/all_results.html#implement-details\">7.3. Implement Details</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/uctb_group.html#pi\">8.1. PI</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/uctb_group.html#key-contributors\">8.2. Key Contributors</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"md_file/uctb_group.html#past-contributors\">8.3. Past Contributors</a></li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"md_file/introduction.html\" class=\"btn btn-neutral float-right\" title=\"1. Introduction\" accesskey=\"n\">Next →</a>\n      \n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/all_results.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>7. Benchmark &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"8. About us (UCTB Group)\" href=\"uctb_group.html\"/>\n        <link rel=\"prev\" title=\"6.7. UCTB.utils package\" href=\"../UCTB.utils.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">7. Benchmark</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#datasets\">7.1. Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#results\">7.2. Results</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#minute-prediction-tasks\">7.2.1. 15-minute prediction tasks</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#results-on-30-minute-prediction-tasks\">7.2.2. Results on 30-minute prediction tasks</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#results-on-60-minute-prediction-tasks\">7.2.3. Results on 60-minute prediction tasks</a></li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#implement-details\">7.3. Implement Details</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#search-space\">7.3.1. Search Space</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#bike-sharing\">7.3.2. Bike-sharing</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#ride-sharing\">7.3.3. Ride-sharing</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#metro-passenger\">7.3.4. Metro Passenger</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#electric-vehicle\">7.3.5. Electric Vehicle</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#traffic-speed\">7.3.6. Traffic Speed</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>7. Benchmark</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/all_results.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"benchmark\">\n<h1>7. Benchmark<a class=\"headerlink\" href=\"#benchmark\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"datasets\">\n<h2>7.1. Datasets<a class=\"headerlink\" href=\"#datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\">Application</th>\n<th align=\"center\">Bike-sharing</th>\n<th align=\"center\">Bike-sharing</th>\n<th align=\"center\">Bike-sharing</th>\n<th align=\"center\">Ride-sharing</th>\n<th align=\"center\">Ride-sharing</th>\n<th align=\"center\">Metro</th>\n<th align=\"center\">Metro</th>\n<th align=\"center\">EV</th>\n<th align=\"center\">Traffic Speed</th>\n<th align=\"center\">Traffic Speed</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">City</td>\n<td align=\"center\"><em>New York City</em></td>\n<td align=\"center\"><em>Chicago</em></td>\n<td align=\"center\"><em>DC</em></td>\n<td align=\"center\"><em>Xi'an</em></td>\n<td align=\"center\"><em>Chengdu</em></td>\n<td align=\"center\"><em>Chongqing</em></td>\n<td align=\"center\"><em>Shanghai</em></td>\n<td align=\"center\"><em>Beijing</em></td>\n<td align=\"center\"><em>METR-LA</em></td>\n<td align=\"center\"><em>PEMS-BAY</em></td>\n</tr>\n<tr>\n<td align=\"left\">Time span</td>\n<td align=\"center\">2013.03-2017.09</td>\n<td align=\"center\">2013.07-2017.09</td>\n<td align=\"center\">2013.07-2017.09</td>\n<td align=\"center\">2016.10-2016.11</td>\n<td align=\"center\">2016.10-2016.11</td>\n<td align=\"center\">2016.08-2017.07</td>\n<td align=\"center\">2016.07-2016.09</td>\n<td align=\"center\">2018.03-2018.05</td>\n<td align=\"center\">2012.03-2012.06</td>\n<td align=\"center\">2017.01-2017.07</td>\n</tr>\n<tr>\n<td align=\"left\">Number of riding records</td>\n<td align=\"center\">49,100,694</td>\n<td align=\"center\">13,130,969</td>\n<td align=\"center\">13,763,675</td>\n<td align=\"center\">5,922,961</td>\n<td align=\"center\">8,439,537</td>\n<td align=\"center\">409,277,117</td>\n<td align=\"center\">333,149,034</td>\n<td align=\"center\">1,272,961</td>\n<td align=\"center\">34,272</td>\n<td align=\"center\">52,128</td>\n</tr>\n<tr>\n<td align=\"left\">Number of stations</td>\n<td align=\"center\">820</td>\n<td align=\"center\">585</td>\n<td align=\"center\">532</td>\n<td align=\"center\">256</td>\n<td align=\"center\">256</td>\n<td align=\"center\">113</td>\n<td align=\"center\">288</td>\n<td align=\"center\">629</td>\n<td align=\"center\">207</td>\n<td align=\"center\">325</td>\n</tr>\n</tbody>\n</table><p>Following shows the map-visualization of stations in NYC, Chicago, DC, Xian and Chengdu.</p>\n<p><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_NYC.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_Chicago.jpg\" style=\"zoom:23%;height:800px;width:800px;\"/> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_DC.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/DiDi_Xian.jpg\" style=\"zoom:23%;height:800px;width:800px;\" />  <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/DiDi_Chengdu.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /></p>\n<p>Following shows the map-visualization of stations in Chongqing, Shanghai and Beijing, METR-LA and PEMS-BAY.</p>\n<p><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Metro_Chongqing.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Metro_Shanghai.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/EV_Beijing.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/METR_LA.png\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/PEMS_BAY.png\" style=\"zoom:23%;height:800px;width:800px;\" /></p>\n</div>\n<div class=\"section\" id=\"results\">\n<h2>7.2. Results<a class=\"headerlink\" href=\"#results\" title=\"Permalink to this headline\">¶</a></h2>\n<p>We conducted experiments on the following datasets at the granularity of 15 minutes, 30 minutes, and 60 minutes respectively. More details and conclusions can be found in the this paper.  <a class=\"reference external\" href=\"https://ieeexplore.ieee.org/document/9627543\">IEEE Xplore</a>, <a class=\"reference external\" href=\"https://arxiv.org/abs/2009.09379\">arXiv</a></p>\n<div class=\"section\" id=\"minute-prediction-tasks\">\n<h3>7.2.1. 15-minute prediction tasks<a class=\"headerlink\" href=\"#minute-prediction-tasks\" title=\"Permalink to this headline\">¶</a></h3>\n<p>The best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\"></th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n<th align=\"center\">Xi'an</th>\n<th align=\"center\">Chengdu</th>\n<th align=\"center\">Shanghai</th>\n<th align=\"center\">Chongqing</th>\n<th align=\"center\">METR-LA</th>\n<th align=\"center\">PEMS-BAY</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">HM (TC)</td>\n<td align=\"center\">1.903</td>\n<td align=\"center\">1.756</td>\n<td align=\"center\">1.655</td>\n<td align=\"center\">3.155</td>\n<td align=\"center\">4.050</td>\n<td align=\"center\">93.81</td>\n<td align=\"center\">76.67</td>\n<td align=\"center\">7.150</td>\n<td align=\"center\">2.967</td>\n</tr>\n<tr>\n<td align=\"left\">ARIMA (TC)</td>\n<td align=\"center\">1.874</td>\n<td align=\"center\">1.784</td>\n<td align=\"center\">1.689</td>\n<td align=\"center\">3.088</td>\n<td align=\"center\">3.948</td>\n<td align=\"center\">83.54</td>\n<td align=\"center\">67.11</td>\n<td align=\"center\">7.028</td>\n<td align=\"center\">2.869</td>\n</tr>\n<tr>\n<td align=\"left\">LSTM  (TC)</td>\n<td align=\"center\">1.989</td>\n<td align=\"center\">1.802</td>\n<td align=\"center\">1.678</td>\n<td align=\"center\">3.051</td>\n<td align=\"center\">3.888</td>\n<td align=\"center\">80.40</td>\n<td align=\"center\">55.37</td>\n<td align=\"center\">6.380</td>\n<td align=\"center\">2.690</td>\n</tr>\n<tr>\n<td align=\"left\">HM (TM)</td>\n<td align=\"center\">1.892</td>\n<td align=\"center\">1.668</td>\n<td align=\"center\">1.555</td>\n<td align=\"center\">2.828</td>\n<td align=\"center\">3.347</td>\n<td align=\"center\">49.75</td>\n<td align=\"center\">45.26</td>\n<td align=\"center\">8.934</td>\n<td align=\"center\">3.690</td>\n</tr>\n<tr>\n<td align=\"left\">XGBoost (TM)</td>\n<td align=\"center\">1.712</td>\n<td align=\"center\">1.672</td>\n<td align=\"center\">1.559</td>\n<td align=\"center\">2.799</td>\n<td align=\"center\">3.430</td>\n<td align=\"center\">47.89</td>\n<td align=\"center\">35.70</td>\n<td align=\"center\">6.443</td>\n<td align=\"center\">2.623</td>\n</tr>\n<tr>\n<td align=\"left\">GBRT (TM)</td>\n<td align=\"center\">1.708</td>\n<td align=\"center\">1.667</td>\n<td align=\"center\">1.552</td>\n<td align=\"center\">2.775</td>\n<td align=\"center\">3.363</td>\n<td align=\"center\">44.55</td>\n<td align=\"center\">33.29</td>\n<td align=\"center\">6.371</td>\n<td align=\"center\">2.645</td>\n</tr>\n<tr>\n<td align=\"left\">TMeta-LSTM-GAL (TM)</td>\n<td align=\"center\">1.818</td>\n<td align=\"center\">1.623</td>\n<td align=\"center\">1.540</td>\n<td align=\"center\">2.917</td>\n<td align=\"center\">3.286</td>\n<td align=\"center\">45.88</td>\n<td align=\"center\">33.34</td>\n<td align=\"center\">6.156</td>\n<td align=\"center\">2.544</td>\n</tr>\n<tr>\n<td align=\"left\">DCRNN (TC+SP)</td>\n<td align=\"center\">1.712</td>\n<td align=\"center\">1.718</td>\n<td align=\"center\">1.594</td>\n<td align=\"center\">2.889</td>\n<td align=\"center\">3.743</td>\n<td align=\"center\">56.00</td>\n<td align=\"center\">37.07</td>\n<td align=\"center\">6.440</td>\n<td align=\"center\">5.322</td>\n</tr>\n<tr>\n<td align=\"left\">STGCN (TC+SP)</td>\n<td align=\"center\">1.738</td>\n<td align=\"center\">1.806</td>\n<td align=\"center\">1.630</td>\n<td align=\"center\">2.789</td>\n<td align=\"center\">3.453</td>\n<td align=\"center\">47.40</td>\n<td align=\"center\">35.19</td>\n<td align=\"center\">6.236</td>\n<td align=\"center\">2.493</td>\n</tr>\n<tr>\n<td align=\"left\">GMAN (TC+SP)</td>\n<td align=\"center\"><strong>1.632</strong>*</td>\n<td align=\"center\"><strong>1.529</strong></td>\n<td align=\"center\"><strong>1.355</strong>*</td>\n<td align=\"center\">2.769</td>\n<td align=\"center\">3.520</td>\n<td align=\"center\">49.21</td>\n<td align=\"center\">36.66</td>\n<td align=\"center\">6.214</td>\n<td align=\"center\">3.484</td>\n</tr>\n<tr>\n<td align=\"left\">Graph-WaveNet (TC+SP+SD)</td>\n<td align=\"center\"><strong>1.644</strong></td>\n<td align=\"center\"><strong>1.460</strong>*</td>\n<td align=\"center\"><strong>1.357</strong></td>\n<td align=\"center\">2.764</td>\n<td align=\"center\">3.442</td>\n<td align=\"center\">47.84</td>\n<td align=\"center\">35.04</td>\n<td align=\"center\"><strong>5.270</strong>*</td>\n<td align=\"center\">2.780</td>\n</tr>\n<tr>\n<td align=\"left\">ST-ResNet (TM+SP)</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">2.686</td>\n<td align=\"center\">3.314</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n</tr>\n<tr>\n<td align=\"left\">ST-MGCN (TM+SM)</td>\n<td align=\"center\">1.687</td>\n<td align=\"center\">1.646</td>\n<td align=\"center\">1.545</td>\n<td align=\"center\">2.714</td>\n<td align=\"center\">3.293</td>\n<td align=\"center\">46.54</td>\n<td align=\"center\"><strong>32.72</strong></td>\n<td align=\"center\">6.645</td>\n<td align=\"center\"><strong>2.426</strong>*</td>\n</tr>\n<tr>\n<td align=\"left\">AGCRN-CDW (TM+SD)</td>\n<td align=\"center\">1.836</td>\n<td align=\"center\">1.883</td>\n<td align=\"center\">1.745</td>\n<td align=\"center\">2.722</td>\n<td align=\"center\">3.296</td>\n<td align=\"center\">77.06</td>\n<td align=\"center\">46.95</td>\n<td align=\"center\">6.709</td>\n<td align=\"center\">2.453</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-GAL (TM+SM)</td>\n<td align=\"center\">1.659</td>\n<td align=\"center\">1.607</td>\n<td align=\"center\">1.527</td>\n<td align=\"center\">2.653</td>\n<td align=\"center\"><strong>3.244</strong></td>\n<td align=\"center\"><strong>41.67</strong></td>\n<td align=\"center\"><strong>31.39</strong>*</td>\n<td align=\"center\"><strong>5.644</strong></td>\n<td align=\"center\"><strong>2.433</strong></td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-CON (TM+SM)</td>\n<td align=\"center\">1.673</td>\n<td align=\"center\">1.629</td>\n<td align=\"center\">1.512</td>\n<td align=\"center\"><strong>2.637</strong>*</td>\n<td align=\"center\"><strong>3.241</strong>*</td>\n<td align=\"center\">43.83</td>\n<td align=\"center\">38.21</td>\n<td align=\"center\">5.800</td>\n<td align=\"center\">2.449</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-DCG-GAL (TM+SM)</td>\n<td align=\"center\">1.654</td>\n<td align=\"center\">1.609</td>\n<td align=\"center\">1.517</td>\n<td align=\"center\"><strong>2.648</strong></td>\n<td align=\"center\">3.254</td>\n<td align=\"center\"><strong>40.94</strong>*</td>\n<td align=\"center\">36.90</td>\n<td align=\"center\">5.788</td>\n<td align=\"center\">2.446</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"results-on-30-minute-prediction-tasks\">\n<h3>7.2.2. Results on 30-minute prediction tasks<a class=\"headerlink\" href=\"#results-on-30-minute-prediction-tasks\" title=\"Permalink to this headline\">¶</a></h3>\n<p>The best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\"></th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n<th align=\"center\">Xi'an</th>\n<th align=\"center\">Chengdu</th>\n<th align=\"center\">Shanghai</th>\n<th align=\"center\">Chongqing</th>\n<th align=\"center\">Beijing</th>\n<th align=\"center\">METR-LA</th>\n<th align=\"center\">PEMS-BAY</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">HM (TC)</td>\n<td align=\"center\">3.206</td>\n<td align=\"center\">2.458</td>\n<td align=\"center\">2.304</td>\n<td align=\"center\">5.280</td>\n<td align=\"center\">6.969</td>\n<td align=\"center\">269.16</td>\n<td align=\"center\">221.39</td>\n<td align=\"center\">0.768</td>\n<td align=\"center\">9.471</td>\n<td align=\"center\">4.155</td>\n</tr>\n<tr>\n<td align=\"left\">ARIMA (TC)</td>\n<td align=\"center\">3.178</td>\n<td align=\"center\">2.428</td>\n<td align=\"center\">2.228</td>\n<td align=\"center\">5.035</td>\n<td align=\"center\">6.618</td>\n<td align=\"center\">212.01</td>\n<td align=\"center\">180.53</td>\n<td align=\"center\">0.755</td>\n<td align=\"center\">9.230</td>\n<td align=\"center\">3.936</td>\n</tr>\n<tr>\n<td align=\"left\">LSTM  (TC)</td>\n<td align=\"center\">3.018</td>\n<td align=\"center\">2.493</td>\n<td align=\"center\">2.212</td>\n<td align=\"center\">4.950</td>\n<td align=\"center\">6.444</td>\n<td align=\"center\">195.60</td>\n<td align=\"center\">104.61</td>\n<td align=\"center\">0.755</td>\n<td align=\"center\">7.866</td>\n<td align=\"center\">3.683</td>\n</tr>\n<tr>\n<td align=\"left\">HM (TM)</td>\n<td align=\"center\">2.686</td>\n<td align=\"center\">2.230</td>\n<td align=\"center\">1.956</td>\n<td align=\"center\">4.239</td>\n<td align=\"center\">4.851</td>\n<td align=\"center\">108.59</td>\n<td align=\"center\">74.55</td>\n<td align=\"center\">0.864</td>\n<td align=\"center\">9.560</td>\n<td align=\"center\">3.965</td>\n</tr>\n<tr>\n<td align=\"left\">XGBoost (TM)</td>\n<td align=\"center\">2.704</td>\n<td align=\"center\">2.376</td>\n<td align=\"center\">1.956</td>\n<td align=\"center\">4.172</td>\n<td align=\"center\">4.915</td>\n<td align=\"center\">81.82</td>\n<td align=\"center\">69.50</td>\n<td align=\"center\">0.686</td>\n<td align=\"center\">8.298</td>\n<td align=\"center\">3.253</td>\n</tr>\n<tr>\n<td align=\"left\">GBRT (TM)</td>\n<td align=\"center\">2.682</td>\n<td align=\"center\">2.355</td>\n<td align=\"center\">1.928</td>\n<td align=\"center\">4.135</td>\n<td align=\"center\">4.873</td>\n<td align=\"center\">83.94</td>\n<td align=\"center\">72.99</td>\n<td align=\"center\">0.689</td>\n<td align=\"center\">8.269</td>\n<td align=\"center\">3.370</td>\n</tr>\n<tr>\n<td align=\"left\">TMeta-LSTM-GAL (TM)</td>\n<td align=\"center\">2.511</td>\n<td align=\"center\"><strong>2.133</strong>*</td>\n<td align=\"center\">1.927</td>\n<td align=\"center\">3.847</td>\n<td align=\"center\">4.678</td>\n<td align=\"center\">85.19</td>\n<td align=\"center\">53.18</td>\n<td align=\"center\">0.686</td>\n<td align=\"center\">7.436</td>\n<td align=\"center\">3.231</td>\n</tr>\n<tr>\n<td align=\"left\">DCRNN (TC+SP)</td>\n<td align=\"center\">2.618</td>\n<td align=\"center\">2.246</td>\n<td align=\"center\">2.118</td>\n<td align=\"center\">4.529</td>\n<td align=\"center\">6.258</td>\n<td align=\"center\">116.15</td>\n<td align=\"center\">65.72</td>\n<td align=\"center\">0.757</td>\n<td align=\"center\">8.562</td>\n<td align=\"center\">6.198</td>\n</tr>\n<tr>\n<td align=\"left\">STGCN (TC+SP)</td>\n<td align=\"center\">2.841</td>\n<td align=\"center\">2.482</td>\n<td align=\"center\">2.067</td>\n<td align=\"center\">3.992</td>\n<td align=\"center\">5.051</td>\n<td align=\"center\">91.29</td>\n<td align=\"center\">58.34</td>\n<td align=\"center\">0.694</td>\n<td align=\"center\">7.871</td>\n<td align=\"center\">3.136</td>\n</tr>\n<tr>\n<td align=\"left\">GMAN (TC+SP)</td>\n<td align=\"center\">2.792</td>\n<td align=\"center\">2.336</td>\n<td align=\"center\"><strong>1.836</strong>*</td>\n<td align=\"center\">4.026</td>\n<td align=\"center\">5.293</td>\n<td align=\"center\">97.58</td>\n<td align=\"center\">51.37</td>\n<td align=\"center\">0.764</td>\n<td align=\"center\">7.276</td>\n<td align=\"center\">3.688</td>\n</tr>\n<tr>\n<td align=\"left\">Graph-WaveNet (TC+SP+SD)</td>\n<td align=\"center\">2.666</td>\n<td align=\"center\">2.158</td>\n<td align=\"center\">1.874</td>\n<td align=\"center\">3.986</td>\n<td align=\"center\">5.097</td>\n<td align=\"center\">92.88</td>\n<td align=\"center\">52.52</td>\n<td align=\"center\">0.719</td>\n<td align=\"center\"><strong>6.809</strong>*</td>\n<td align=\"center\">3.589</td>\n</tr>\n<tr>\n<td align=\"left\">ST-ResNet (TM+SP)</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">3.903</td>\n<td align=\"center\">4.673</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n</tr>\n<tr>\n<td align=\"left\">ST-MGCN (TM+SM)</td>\n<td align=\"center\">2.513</td>\n<td align=\"center\">2.177</td>\n<td align=\"center\">1.903</td>\n<td align=\"center\">3.886</td>\n<td align=\"center\">4.732</td>\n<td align=\"center\">88.76</td>\n<td align=\"center\">50.96</td>\n<td align=\"center\">0.691</td>\n<td align=\"center\">8.079</td>\n<td align=\"center\"><strong>3.042</strong></td>\n</tr>\n<tr>\n<td align=\"left\">AGCRN-CDW (TM+SD)</td>\n<td align=\"center\">2.830</td>\n<td align=\"center\">2.565</td>\n<td align=\"center\">2.074</td>\n<td align=\"center\">3.958</td>\n<td align=\"center\">4.753</td>\n<td align=\"center\">238.99</td>\n<td align=\"center\">131.55</td>\n<td align=\"center\">0.688</td>\n<td align=\"center\">8.575</td>\n<td align=\"center\"><strong>3.022</strong>*</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-GAL (TM+SM)</td>\n<td align=\"center\"><strong>2.410</strong>*</td>\n<td align=\"center\">2.170</td>\n<td align=\"center\">1.856</td>\n<td align=\"center\"><strong>3.808</strong></td>\n<td align=\"center\">4.650</td>\n<td align=\"center\"><strong>75.36</strong>*</td>\n<td align=\"center\"><strong>49.47</strong></td>\n<td align=\"center\"><strong>0.670</strong></td>\n<td align=\"center\">7.156</td>\n<td align=\"center\">3.116</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-CON (TM+SM)</td>\n<td align=\"center\"><strong>2.411</strong></td>\n<td align=\"center\"><strong>2.133</strong>*</td>\n<td align=\"center\">1.859</td>\n<td align=\"center\"><strong>3.772</strong>*</td>\n<td align=\"center\"><strong>4.613</strong>*</td>\n<td align=\"center\">80.69</td>\n<td align=\"center\">50.01</td>\n<td align=\"center\"><strong>0.667</strong>*</td>\n<td align=\"center\"><strong>6.889</strong>*</td>\n<td align=\"center\">3.204</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-DCG-GAL (TM+SM)</td>\n<td align=\"center\"><strong>2.411</strong></td>\n<td align=\"center\">2.182</td>\n<td align=\"center\"><strong>1.852</strong></td>\n<td align=\"center\">3.833</td>\n<td align=\"center\"><strong>4.635</strong></td>\n<td align=\"center\"><strong>77.49</strong></td>\n<td align=\"center\"><strong>48.96</strong>*</td>\n<td align=\"center\"><strong>0.670</strong></td>\n<td align=\"center\">7.184</td>\n<td align=\"center\">3.187</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"results-on-60-minute-prediction-tasks\">\n<h3>7.2.3. Results on 60-minute prediction tasks<a class=\"headerlink\" href=\"#results-on-60-minute-prediction-tasks\" title=\"Permalink to this headline\">¶</a></h3>\n<p>The best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\"></th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n<th align=\"center\">Xi'an</th>\n<th align=\"center\">Chengdu</th>\n<th align=\"center\">Shanghai</th>\n<th align=\"center\">Chongqing</th>\n<th align=\"center\">Beijing</th>\n<th align=\"center\">METR-LA</th>\n<th align=\"center\">PEMS-BAY</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">HM (TC)</td>\n<td align=\"center\">5.814</td>\n<td align=\"center\">4.143</td>\n<td align=\"center\">3.485</td>\n<td align=\"center\">10.136</td>\n<td align=\"center\">14.145</td>\n<td align=\"center\">824.94</td>\n<td align=\"center\">673.55</td>\n<td align=\"center\">1.178</td>\n<td align=\"center\">12.303</td>\n<td align=\"center\">5.779</td>\n</tr>\n<tr>\n<td align=\"left\">ARIMA (TC)</td>\n<td align=\"center\">5.289</td>\n<td align=\"center\">3.744</td>\n<td align=\"center\">3.183</td>\n<td align=\"center\">9.475</td>\n<td align=\"center\">13.259</td>\n<td align=\"center\">676.79</td>\n<td align=\"center\">578.19</td>\n<td align=\"center\">0.982</td>\n<td align=\"center\">11.739</td>\n<td align=\"center\">5.670</td>\n</tr>\n<tr>\n<td align=\"left\">LSTM  (TC)</td>\n<td align=\"center\">5.167</td>\n<td align=\"center\">3.721</td>\n<td align=\"center\">3.234</td>\n<td align=\"center\">9.830</td>\n<td align=\"center\">13.483</td>\n<td align=\"center\">506.07</td>\n<td align=\"center\">322.81</td>\n<td align=\"center\">0.999</td>\n<td align=\"center\">10.083</td>\n<td align=\"center\">4.777</td>\n</tr>\n<tr>\n<td align=\"left\">HM (TM)</td>\n<td align=\"center\">3.992</td>\n<td align=\"center\">3.104</td>\n<td align=\"center\">2.632</td>\n<td align=\"center\">6.186</td>\n<td align=\"center\">7.512</td>\n<td align=\"center\">172.55</td>\n<td align=\"center\">119.86</td>\n<td align=\"center\">1.016</td>\n<td align=\"center\">10.727</td>\n<td align=\"center\">4.018</td>\n</tr>\n<tr>\n<td align=\"left\">XGBoost (TM)</td>\n<td align=\"center\">4.102</td>\n<td align=\"center\">3.003</td>\n<td align=\"center\">2.643</td>\n<td align=\"center\">6.733</td>\n<td align=\"center\">7.592</td>\n<td align=\"center\">160.38</td>\n<td align=\"center\">117.05</td>\n<td align=\"center\">0.834</td>\n<td align=\"center\">10.299</td>\n<td align=\"center\">3.703</td>\n</tr>\n<tr>\n<td align=\"left\">GBRT (TM)</td>\n<td align=\"center\">4.039</td>\n<td align=\"center\">2.984</td>\n<td align=\"center\">2.611</td>\n<td align=\"center\">6.446</td>\n<td align=\"center\">7.511</td>\n<td align=\"center\">154.29</td>\n<td align=\"center\">113.92</td>\n<td align=\"center\">0.828</td>\n<td align=\"center\">10.013</td>\n<td align=\"center\">3.704</td>\n</tr>\n<tr>\n<td align=\"left\">TMeta-LSTM-GAL (TM)</td>\n<td align=\"center\">3.739</td>\n<td align=\"center\">2.840</td>\n<td align=\"center\">2.557</td>\n<td align=\"center\"><strong>5.843</strong></td>\n<td align=\"center\">6.949</td>\n<td align=\"center\">163.31</td>\n<td align=\"center\">102.86</td>\n<td align=\"center\">0.840</td>\n<td align=\"center\"><strong>8.670</strong>*</td>\n<td align=\"center\">3.616</td>\n</tr>\n<tr>\n<td align=\"left\">DCRNN (TC+SP)</td>\n<td align=\"center\">4.187</td>\n<td align=\"center\">3.081</td>\n<td align=\"center\">3.016</td>\n<td align=\"center\">8.203</td>\n<td align=\"center\">11.444</td>\n<td align=\"center\">340.25</td>\n<td align=\"center\">122.31</td>\n<td align=\"center\">0.989</td>\n<td align=\"center\">11.121</td>\n<td align=\"center\">6.920</td>\n</tr>\n<tr>\n<td align=\"left\">STGCN (TC+SP)</td>\n<td align=\"center\">3.895</td>\n<td align=\"center\">2.989</td>\n<td align=\"center\">2.597</td>\n<td align=\"center\">6.150</td>\n<td align=\"center\">7.710</td>\n<td align=\"center\">187.98</td>\n<td align=\"center\">106.16</td>\n<td align=\"center\">0.859</td>\n<td align=\"center\">10.688</td>\n<td align=\"center\">3.472</td>\n</tr>\n<tr>\n<td align=\"left\">GMAN (TC+SP)</td>\n<td align=\"center\">4.251</td>\n<td align=\"center\">2.875</td>\n<td align=\"center\">2.530</td>\n<td align=\"center\">7.099</td>\n<td align=\"center\">13.351</td>\n<td align=\"center\">193.39</td>\n<td align=\"center\">117.52</td>\n<td align=\"center\">0.949</td>\n<td align=\"center\">10.012</td>\n<td align=\"center\">3.846</td>\n</tr>\n<tr>\n<td align=\"left\">Graph-WaveNet (TC+SP+SD)</td>\n<td align=\"center\">3.863</td>\n<td align=\"center\">2.812</td>\n<td align=\"center\"><strong>2.403</strong>*</td>\n<td align=\"center\">6.541</td>\n<td align=\"center\">8.162</td>\n<td align=\"center\">186.82</td>\n<td align=\"center\">102.75</td>\n<td align=\"center\">0.930</td>\n<td align=\"center\">9.463</td>\n<td align=\"center\">4.135</td>\n</tr>\n<tr>\n<td align=\"left\">ST-ResNet (TM+SP)</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">6.075</td>\n<td align=\"center\">7.155</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n<td align=\"center\">---</td>\n</tr>\n<tr>\n<td align=\"left\">ST-MGCN (TM+SM)</td>\n<td align=\"center\">3.723</td>\n<td align=\"center\">2.904</td>\n<td align=\"center\">2.518</td>\n<td align=\"center\">5.878</td>\n<td align=\"center\">7.067</td>\n<td align=\"center\">159.52</td>\n<td align=\"center\">104.87</td>\n<td align=\"center\">0.827</td>\n<td align=\"center\">10.798</td>\n<td align=\"center\"><strong>3.486</strong></td>\n</tr>\n<tr>\n<td align=\"left\">AGCRN-CDW (TM+SD)</td>\n<td align=\"center\">3.795</td>\n<td align=\"center\">2.935</td>\n<td align=\"center\">2.580</td>\n<td align=\"center\">8.835</td>\n<td align=\"center\">10.275</td>\n<td align=\"center\">658.12</td>\n<td align=\"center\">287.41</td>\n<td align=\"center\">0.844</td>\n<td align=\"center\">10.728</td>\n<td align=\"center\"><strong>3.381</strong>*</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-GAL (TM+SM)</td>\n<td align=\"center\"><strong>3.518</strong></td>\n<td align=\"center\"><strong>2.695</strong></td>\n<td align=\"center\">2.405</td>\n<td align=\"center\">5.871</td>\n<td align=\"center\"><strong>6.858</strong>*</td>\n<td align=\"center\">153.17</td>\n<td align=\"center\"><strong>97.87</strong></td>\n<td align=\"center\">0.831</td>\n<td align=\"center\"><strong>8.834</strong></td>\n<td align=\"center\">3.514</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-GCL-CON (TM+SM)</td>\n<td align=\"center\"><strong>3.507</strong>*</td>\n<td align=\"center\">2.739</td>\n<td align=\"center\"><strong>2.404</strong></td>\n<td align=\"center\"><strong>5.829</strong>*</td>\n<td align=\"center\"><strong>6.873</strong></td>\n<td align=\"center\"><strong>149.05</strong></td>\n<td align=\"center\">106.41</td>\n<td align=\"center\"><strong>0.807</strong></td>\n<td align=\"center\">9.147</td>\n<td align=\"center\">3.552</td>\n</tr>\n<tr>\n<td align=\"left\">STMeta-DCG-GAL (TM+SM)</td>\n<td align=\"center\">3.521</td>\n<td align=\"center\"><strong>2.652</strong>*</td>\n<td align=\"center\">2.423</td>\n<td align=\"center\">5.908</td>\n<td align=\"center\">6.904</td>\n<td align=\"center\"><strong>143.18</strong>*</td>\n<td align=\"center\"><strong>94.78</strong>*</td>\n<td align=\"center\"><strong>0.803</strong>*</td>\n<td align=\"center\">8.993</td>\n<td align=\"center\">3.500</td>\n</tr>\n</tbody>\n</table></div>\n</div>\n<div class=\"section\" id=\"implement-details\">\n<h2>7.3. Implement Details<a class=\"headerlink\" href=\"#implement-details\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"search-space\">\n<h3>7.3.1. Search Space<a class=\"headerlink\" href=\"#search-space\" title=\"Permalink to this headline\">¶</a></h3>\n<p>We use <a class=\"reference external\" href=\"https://github.com/microsoft/nni\">nni</a> toolkit to search the best parameters of HM, XGBoost and GBRT model. Search space are following.</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">Model</th>\n<th align=\"center\">Search Space</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>CT: 0~6</code>, <code>PT: 0~7</code>, <code>TT: 0~4</code></td>\n</tr>\n<tr>\n<td align=\"center\">ARIMA</td>\n<td align=\"center\"><code>CT:168</code>,<code>p:3</code>, <code>d:0</code>, <code>q:0</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>CT: 0~12</code>, <code>PT: 0~14</code>, <code>TT: 0~4</code>, <code>estimater: 10~200</code>, <code>depth: 2~10</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>CT: 0~12</code>, <code>PT: 0~14</code>, <code>TT: 0~4</code>, <code>estimater: 10~200</code>, <code>depth: 2~10</code></td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"bike-sharing\">\n<h3>7.3.2. Bike-sharing<a class=\"headerlink\" href=\"#bike-sharing\" title=\"Permalink to this headline\">¶</a></h3>\n<ul class=\"simple\">\n<li>HM &amp; XGBoost &amp; GBRT</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">15 minutes</th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>3-1-2</code></td>\n<td align=\"center\"><code>5-0-4</code></td>\n<td align=\"center\"><code>3-7-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>8-14-4-32-2</code></td>\n<td align=\"center\"><code>11-13-4-28-2</code></td>\n<td align=\"center\"><code>4-14-4-27-2</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>7-13-4-144-1</code></td>\n<td align=\"center\"><code>7-15-4-101-2</code></td>\n<td align=\"center\"><code>8-11-5-101-2</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">30 minutes</th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-1-2</code></td>\n<td align=\"center\"><code>3-2-1</code></td>\n<td align=\"center\"><code>3-1-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>12-8-1-36-3</code></td>\n<td align=\"center\"><code>7-5-2-24-2</code></td>\n<td align=\"center\"><code>12-13-4-27-2</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>12-10-0-72-4</code></td>\n<td align=\"center\"><code>9-13-2-91-2</code></td>\n<td align=\"center\"><code>13-15-5-140-1</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">60 minutes</th>\n<th align=\"center\">NYC</th>\n<th align=\"center\">Chicago</th>\n<th align=\"center\">DC</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>1-1-3</code></td>\n<td align=\"center\"><code>1-1-1</code></td>\n<td align=\"center\"><code>2-1-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>13-7-0-103-3</code></td>\n<td align=\"center\"><code>11-8-0-35-4</code></td>\n<td align=\"center\"><code>11-9-5-28-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>12-6-1-58-5</code></td>\n<td align=\"center\"><code>11-8-1-92-5</code></td>\n<td align=\"center\"><code>11-8-5-54-3</code></td>\n</tr>\n</tbody>\n</table><ul>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/bike_trial.py\">ST_MGCN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/bike_trial.py\">DCRNN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\">LSTM &amp; TMeta-LSTM-GAL &amp; STMeta-V1  &amp; STMeta-V2  &amp; STMeta-V3</p>\n<p>These five models can be run by specifying data files and model files on  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py\">STMeta_Obj.py</a>.</p>\n<p>Data Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_nyc.data.yml\">bike_nyc.data.yml</a> , <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_chicago.data.yml\">bike_chicago.data.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_dc.data.yml\">bike_dc.data.yml</a></p>\n<p>Model Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml\">STMeta_v0.model.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml\">STMeta_v1.model.yml</a>.,  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml\">STMeta_v2.model.yml</a>., <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml\">STMeta_v3.model.yml</a>.</p>\n<ul class=\"simple\">\n<li>LSTM</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<ul class=\"simple\">\n<li>TMeta-LSTM-GAL</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<ul class=\"simple\">\n<li>STMeta-V1</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<ul class=\"simple\">\n<li>STMeta-V2</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<ul class=\"simple\">\n<li>STMeta-V3</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"ride-sharing\">\n<h3>7.3.3. Ride-sharing<a class=\"headerlink\" href=\"#ride-sharing\" title=\"Permalink to this headline\">¶</a></h3>\n<ul class=\"simple\">\n<li>HM &amp; XGBoost &amp; GBRT</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">15 minutes</th>\n<th align=\"center\"><strong>Xi'an</strong></th>\n<th align=\"center\"><strong>Chengdu</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>5-0-4</code></td>\n<td align=\"center\"><code>2-7-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>7-14-0-10-4</code></td>\n<td align=\"center\"><code>12-14-1-27-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>11-2-2-45-3</code></td>\n<td align=\"center\"><code>13-15-5-39-3</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">30 minutes</th>\n<th align=\"center\"><strong>Xi'an</strong></th>\n<th align=\"center\"><strong>Chengdu</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-0-2</code></td>\n<td align=\"center\"><code>1-7-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>9-0-2-25-3</code></td>\n<td align=\"center\"><code>9-14-3-16-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>9-0-2-80-3</code></td>\n<td align=\"center\"><code>10-10-5-34-3</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">60 minutes</th>\n<th align=\"center\"><strong>Xi'an</strong></th>\n<th align=\"center\"><strong>Chengdu</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>1-1-2</code></td>\n<td align=\"center\"><code>0-7-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>12-0-2-10-5</code></td>\n<td align=\"center\"><code>9-6-2-14-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>9-0-2-50-2</code></td>\n<td align=\"center\"><code>9-12-2-50-5</code></td>\n</tr>\n</tbody>\n</table><ul class=\"simple\">\n<li>ST-ResNet</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">ST-ResNet Search Space</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\"><code>residual_units:2~6</code>,  <code>conv_filter:[32, 64, 128]</code>,  <code>kernal_size:3~5</code>, <br /><code>lr:[0.0001, 0.00002, 0.00004, 0.00008, 0.00001]</code>, <code>batch_size:[32, 64, 128, 256]</code></td>\n</tr>\n</tbody>\n</table><p>The best parameters found are following.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">args</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n  <span class=\"s1\">&#39;dataset&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;DiDi&#39;</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;city&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;Chengdu&#39;</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;num_residual_unit&#39;</span><span class=\"p\">:</span> <span class=\"mi\">4</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;conv_filters&#39;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;kernel_size&#39;</span><span class=\"p\">:</span> <span class=\"mi\">3</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;lr&#39;</span><span class=\"p\">:</span> <span class=\"mf\">1e-5</span><span class=\"p\">,</span>\n  <span class=\"s1\">&#39;batch_size&#39;</span><span class=\"p\">:</span> <span class=\"mi\">32</span>\n</pre></div>\n</div>\n<p>We can modify <code class=\"docutils literal\"><span class=\"pre\">city</span></code> parameter to <code class=\"docutils literal\"><span class=\"pre\">Chengdu</span></code> or <code class=\"docutils literal\"><span class=\"pre\">Xian</span></code> in <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_ResNet/ST_ResNet.py\">ST_ResNet.py</a> , and then run it.</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span> python ST_ResNet.py \n</pre></div>\n</div>\n<ul>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/didi_trial.py\">ST_MGCN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/didi_trial.py\">DCRNN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\">LSTM &amp; TMeta-LSTM-GAL &amp; STMeta-V1  &amp; STMeta-V2  &amp; STMeta-V3</p>\n<p>These five models can be run by specifying data files and model files on <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py\">STMeta_Obj.py</a>.</p>\n<p>Data Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_xian.data.yml\">didi_xian.data.yml</a> , <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_chengdu.data.yml\">didi_chengdu.data.yml</a>.</p>\n<p>Model Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml\">STMeta_v0.model.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml\">STMeta_v1.model.yml</a>.,  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml\">STMeta_v2.model.yml</a>., <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml\">STMeta_v3.model.yml</a>.</p>\n<ul>\n<li><p class=\"first\">LSTM</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml&#39;</span>\n        <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml&#39;</span>\n        <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">TMeta-LSTM-GAL</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V1</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V2</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V3</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Interaction,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"metro-passenger\">\n<h3>7.3.4. Metro Passenger<a class=\"headerlink\" href=\"#metro-passenger\" title=\"Permalink to this headline\">¶</a></h3>\n<ul class=\"simple\">\n<li>HM &amp; XGBoost &amp; GBRT</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">15 minutes</th>\n<th align=\"center\"><strong>Chongqing</strong></th>\n<th align=\"center\"><strong>Shanghai</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-1-4</code></td>\n<td align=\"center\"><code>1-0-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>12-6-4-51-8</code></td>\n<td align=\"center\"><code>11-10-4-31-7</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>12-14-1-182-7</code></td>\n<td align=\"center\"><code>12-7-1-148-5</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">30 minutes</th>\n<th align=\"center\"><strong>Chongqing</strong></th>\n<th align=\"center\"><strong>Shanghai</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>1-0-4</code></td>\n<td align=\"center\"><code>1-1-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>11-5-0-45-8</code></td>\n<td align=\"center\"><code>12-6-1-206-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>10-3-0-107-8</code></td>\n<td align=\"center\"><code>7-4-1-58-7</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">60 minutes</th>\n<th align=\"center\"><strong>Chongqing</strong></th>\n<th align=\"center\"><strong>Shanghai</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>0-1-4</code></td>\n<td align=\"center\"><code>0-0-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>9-14-2-200-5</code></td>\n<td align=\"center\"><code>3-7-0-50-5</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>12-10-4-200-5</code></td>\n<td align=\"center\"><code>9-5-1-66-6</code></td>\n</tr>\n</tbody>\n</table><ul>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metro_trial.py\">ST_MGCN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metro_trial.py\">DCRNN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\">LSTM &amp; TMeta-LSTM-GAL &amp; STMeta-V1  &amp; STMeta-V2  &amp; STMeta-V3</p>\n<p>These five models can be run by specifying data files and model files on <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py\">STMeta_Obj.py</a>.</p>\n<p>Data Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_chongqing.data.yml\">metro_chongqing.data.yml</a> , <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_shanghai.data.yml\">metro_shanghai.data.yml</a>.</p>\n<p>Model Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml\">STMeta_v0.model.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml\">STMeta_v1.model.yml</a>.,  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml\">STMeta_v2.model.yml</a>., <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml\">STMeta_v3.model.yml</a>.</p>\n<ul>\n<li><p class=\"first\">LSTM</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">TMeta-LSTM-GAL</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V1</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V2</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V3</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml &#39;</span>\n        <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"electric-vehicle\">\n<h3>7.3.5. Electric Vehicle<a class=\"headerlink\" href=\"#electric-vehicle\" title=\"Permalink to this headline\">¶</a></h3>\n<ul class=\"simple\">\n<li>HM &amp; XGBoost &amp; GBRT</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">Beijing</th>\n<th align=\"center\">30 minutes</th>\n<th align=\"center\">60 minutes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-0-0</code></td>\n<td align=\"center\"><code>2-0-2</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>6-6-1-19-2</code></td>\n<td align=\"center\"><code>12-7-0-20-2</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>13-3-2-47-3</code></td>\n<td align=\"center\"><code>12-10-0-100-2</code></td>\n</tr>\n</tbody>\n</table><ul>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/cs_trial.py\">ST_MGCN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/cs_trial.py\">DCRNN</a> Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\">LSTM &amp; TMeta-LSTM-GAL &amp; STMeta-V1  &amp; STMeta-V2  &amp; STMeta-V3</p>\n<p>These five models can be run by specifying data files and model files on <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py\">STMeta_Obj.py</a>.</p>\n<p>Data Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/chargestation_beijing.data.yml\">chargestation_beijing.data.yml</a>.</p>\n<p>Model Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml\">STMeta_v0.model.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml\">STMeta_v1.model.yml</a>.,  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml\">STMeta_v2.model.yml</a>., <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml\">STMeta_v3.model.yml</a>.</p>\n<ul>\n<li><p class=\"first\">LSTM</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:2&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">TMeta-LSTM-GAL</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:1&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:2&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V1</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n        <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V2</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n        <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V3</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"traffic-speed\">\n<h3>7.3.6. Traffic Speed<a class=\"headerlink\" href=\"#traffic-speed\" title=\"Permalink to this headline\">¶</a></h3>\n<ul class=\"simple\">\n<li>HM &amp; XGBoost &amp; GBRT</li>\n</ul>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">15 minutes</th>\n<th align=\"center\"><strong>METR-LA</strong></th>\n<th align=\"center\"><strong>PEMS-BAY</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-0-4</code></td>\n<td align=\"center\"><code>1-0-1</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>11-1-2-25-3</code></td>\n<td align=\"center\"><code>12-4-2-21-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>11-8-2-29-4</code></td>\n<td align=\"center\"><code>10-6-1-65-6</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">30 minutes</th>\n<th align=\"center\"><strong>METR-LA</strong></th>\n<th align=\"center\"><strong>PEMS-BAY</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-0-4</code></td>\n<td align=\"center\"><code>1-0-1</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>6-6-0-25-3</code></td>\n<td align=\"center\"><code>12-13-2-27-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>10-0-0-27-3</code></td>\n<td align=\"center\"><code>12-6-2-90-7</code></td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">60 minutes</th>\n<th align=\"center\"><strong>METR-LA</strong></th>\n<th align=\"center\"><strong>PEMS-BAY</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">HM</td>\n<td align=\"center\"><code>2-1-4</code></td>\n<td align=\"center\"><code>1-1-4</code></td>\n</tr>\n<tr>\n<td align=\"center\">XGBoost</td>\n<td align=\"center\"><code>2-2-0-25-3</code></td>\n<td align=\"center\"><code>12-6-2-19-3</code></td>\n</tr>\n<tr>\n<td align=\"center\">GBRT</td>\n<td align=\"center\"><code>4-5-1-19-4</code></td>\n<td align=\"center\"><code>12-7-2-59-5</code></td>\n</tr>\n</tbody>\n</table><ul>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metr_trial.py\">METR-LA</a>  and <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/pems_trial.py\">PEMS-BAY</a>  ST_MGCN Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\"><a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metr_trial.py\">METR-LA</a> and <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/pems_trial.py\">PEMS-BAY</a> DCRNN Run Code &amp; Setting.</p>\n</li>\n<li><p class=\"first\">LSTM &amp; TMeta-LSTM-GAL &amp; STMeta-V1  &amp; STMeta-V2  &amp; STMeta-V3</p>\n<p>These five models can be run by specifying data files and model files on <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py\">STMeta_Obj.py</a>.</p>\n<p>Data Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metr_la.data.yml\">metr_la.data.yml</a> , <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/pems_bay.data.yml\">pems_bay.data.yml</a>.</p>\n<p>Model Files: <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml\">STMeta_v0.model.yml</a>, <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml\">STMeta_v1.model.yml</a>.,  <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml\">STMeta_v2.model.yml</a>., <a class=\"reference external\" href=\"https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml\">STMeta_v3.model.yml</a>.</p>\n<ul>\n<li><p class=\"first\">LSTM</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml&#39;</span>\n          <span class=\"s1\">&#39; -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">TMeta-LSTM-GAL</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v0.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V1</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v1.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V2</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v2.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n<li><p class=\"first\">STMeta-V3</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj.py -m STMeta_v3.model.yml&#39;</span>\n          <span class=\"s1\">&#39; -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"uctb_group.html\" class=\"btn btn-neutral float-right\" title=\"8. About us (UCTB Group)\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"../UCTB.utils.html\" class=\"btn btn-neutral\" title=\"6.7. UCTB.utils package\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/installation.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>2. Installation &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"3. Urban Datasets\" href=\"urban_dataset.html\"/>\n        <link rel=\"prev\" title=\"1. Introduction\" href=\"introduction.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">2. Installation</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#install-via-anaconda\">2.1. Install via Anaconda</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#check-for-success\">2.2. Check for Success</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#high-version-gpu-framework-support\">2.3. High version GPU Framework support</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#q-a\">2.4. Q &amp; A</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>2. Installation</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/installation.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"installation\">\n<h1>2. Installation<a class=\"headerlink\" href=\"#installation\" title=\"Permalink to this headline\">¶</a></h1>\n<p>UCTB is based on several well-known deep learning frameworks, including <strong>PyTorch</strong>, <strong>TensorFlow</strong>, and <strong>MXNet</strong>. If you have an Nvidia GPU installed on your computer, we highly recommend you install the GPU version of these frameworks.</p>\n<p>UCTB toolbox may not work successfully with the upgrade of some packages. We thus encourage you to use the specific version of packages to avoid unseen errors. <em><strong>To avoid potential conflict, we highly recommend you install UCTB vis Anaconda.</strong></em></p>\n<div class=\"section\" id=\"install-via-anaconda\">\n<h2>2.1. Install via Anaconda<a class=\"headerlink\" href=\"#install-via-anaconda\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Step 1: Install Anaconda</strong></p>\n<p>You can skip to step 2 if you already installed Anaconda.</p>\n<p>To install Anaconda, please refer to this page <a class=\"reference external\" href=\"https://www.anaconda.com/download\">https://www.anaconda.com/download</a>.</p>\n<p><strong>Step 2: create UCTB environment</strong></p>\n<p>Create the UCTB environment by the following command. You may need the <a class=\"reference external\" href=\"https://github.com/uctb/UCTB/blob/master/environment.yaml\">environment.yaml</a> file.</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span>conda env create -f environment.yaml\n</pre></div>\n</div>\n<p>Then activate the UCTB environment and start to use it. 🎉🎉🎉</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span>conda activate UCTB\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"check-for-success\">\n<h2>2.2. Check for Success<a class=\"headerlink\" href=\"#check-for-success\" title=\"Permalink to this headline\">¶</a></h2>\n<p>If you  successfully install UCTB, you may get the following output after importing UCTB.</p>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span>(UCTB) XXX:~$ python\nType &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.\n&gt;&gt;&gt; import UCTB\nUsing TensorFlow backend.\n&gt;&gt;&gt; \n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"high-version-gpu-framework-support\">\n<h2>2.3. High version GPU Framework support<a class=\"headerlink\" href=\"#high-version-gpu-framework-support\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Existing Problems</strong></p>\n<p>Due to changes in the design architecture of high-version GPUs, low-version CUDA is not compatible with high-version GPUs. As a result, Tensorflow 1.x is only compatible with low-version CUDA, leading to runtime failures on machines equipped with high-version GPUs. https://stackoverflow.com/questions/50622525/which-tensorflow-and-cuda-version-combinations-are-compatible</p>\n<p><strong>Solution</strong></p>\n<p>Thanks to the <a class=\"reference external\" href=\"https://github.com/NVIDIA/tensorflow\">Nvidia TensorFlow</a> project, which was created to support newer hardware and improve libraries for NVIDIA GPU users using TensorFlow 1.x, we can now install UCTB on machines with newer GPUs. You can follow the installation tutorial below to start enjoying UCTB.</p>\n<p><strong>Clone the project</strong></p>\n<div class=\"highlight-sh\"><div class=\"highlight\"><pre><span></span>&gt;&gt;&gt; git clone git@github.com:uctb/UCTB.git\n&gt;&gt;&gt; <span class=\"nb\">cd</span> UCTB\n</pre></div>\n</div>\n<p><strong>Create Anaconda Environment</strong></p>\n<div class=\"highlight-sh\"><div class=\"highlight\"><pre><span></span>&gt;&gt;&gt; conda create -n UCTB <span class=\"nv\">python</span><span class=\"o\">=</span><span class=\"m\">3</span>.8\n&gt;&gt;&gt; conda activate UCTB\n</pre></div>\n</div>\n<p><strong>Install Nvidia Tensorflow</strong></p>\n<div class=\"highlight-sh\"><div class=\"highlight\"><pre><span></span>&gt;&gt;&gt; pip install --user nvidia-pyindex\n&gt;&gt;&gt; pip install --user nvidia-tensorflow<span class=\"o\">[</span>horovod<span class=\"o\">]</span>\n</pre></div>\n</div>\n<p><strong>Install UCTB from Source</strong></p>\n<div class=\"highlight-sh\"><div class=\"highlight\"><pre><span></span>&gt;&gt;&gt; python build_install.py\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"q-a\">\n<h2>2.4. Q &amp; A<a class=\"headerlink\" href=\"#q-a\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Q: I fail to install PyTorch, TensorFlow, and MXNet, what is the version number of them?</strong></p>\n<p>A: We recommend you install PyTorch==1.1.0, TensorFlow==1.13.1, and MXNet==1.5.0 with cuda version 10.0. We here give the installation command:</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># Install PyTorch</span>\nconda install <span class=\"nv\">pytorch</span><span class=\"o\">==</span><span class=\"m\">1</span>.1.0 <span class=\"nv\">torchvision</span><span class=\"o\">==</span><span class=\"m\">0</span>.3.0 <span class=\"nv\">cudatoolkit</span><span class=\"o\">=</span><span class=\"m\">10</span>.0 -c pytorch\n\n<span class=\"c1\"># Install TensorFlow</span>\nconda install tensorflow-gpu<span class=\"o\">==</span><span class=\"m\">1</span>.13.1\n\n<span class=\"c1\"># Install MXNet</span>\npip install mxnet-cu100<span class=\"o\">==</span><span class=\"m\">1</span>.5.0\n</pre></div>\n</div>\n<p><strong>Q:  I'm using Windows OS, and my Anaconda reports that it cannot find the PyTorch 1.1.0 packages. How to install it?</strong></p>\n<p>A: You could install it by the following command.</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span>pip install <span class=\"nv\">torch</span><span class=\"o\">==</span><span class=\"m\">1</span>.1.0 <span class=\"nv\">torchvision</span><span class=\"o\">==</span><span class=\"m\">0</span>.3.0 -f https://download.pytorch.org/whl/cu100/torch_stable.html\n</pre></div>\n</div>\n<p><strong>Q:  I fail to install UCTB via pip. How to install it ?</strong></p>\n<p>A: This situation may occur when your OS is Windows. You could install UCTB by its source code. First download UCTB's source code and your folder may look like this:</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span>XXX/UCTB-master# ls\nbuild_install.py  dist  environment.yaml  __init__.py  QuickStarts  setup.py\nbuild.py          docs  Experiments       LICENSE      README.md    UCTB\n</pre></div>\n</div>\n<p>then build and install UCTB by the following command:</p>\n<div class=\"highlight-bash\"><div class=\"highlight\"><pre><span></span>python build_install.py\n</pre></div>\n</div>\n<p><u><a class=\"reference external\" href=\"../index.html\">Back To HomePage</a></u></p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"urban_dataset.html\" class=\"btn btn-neutral float-right\" title=\"3. Urban Datasets\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"introduction.html\" class=\"btn btn-neutral\" title=\"1. Introduction\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/introduction.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>1. Introduction &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"2. Installation\" href=\"installation.html\"/>\n        <link rel=\"prev\" title=\"Welcome to UCTB’s documentation!\" href=\"../index.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">1. Introduction</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#urban-datasts\">1.1. Urban Datasts</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#predictive-tool\">1.2. Predictive Tool</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#visualization-tool\">1.3. Visualization Tool</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>1. Introduction</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/introduction.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"introduction\">\n<h1>1. Introduction<a class=\"headerlink\" href=\"#introduction\" title=\"Permalink to this headline\">¶</a></h1>\n<p><strong>Urban Computing Tool Box</strong> is a package providing <a class=\"reference external\" href=\"https://github.com/uctb/Urban-Dataset\"><strong>urban datasets</strong></a>, <a class=\"reference external\" href=\"https://github.com/uctb/UCTB\"><strong>spatial-temporal prediction models</strong></a>, and <a class=\"reference external\" href=\"https://github.com/uctb/visualization-tool-UCTB\"><strong>visualization tools</strong></a> for various urban computing tasks, such as traffic prediction, crowd flow prediction, ridesharing demand prediction, etc.</p>\n<p>UCTB is a flexible and open package. You can use the data we provided or use your data, and the data structure is well stated in the <a class=\"reference external\" href=\"https://uctb.github.io/UCTB/md_file/tutorial.html\"><strong>tutorial section</strong></a>.</p>\n<div class=\"section\" id=\"urban-datasts\">\n<h2>1.1. Urban Datasts<a class=\"headerlink\" href=\"#urban-datasts\" title=\"Permalink to this headline\">¶</a></h2>\n<p>UCTB also releases <a class=\"reference external\" href=\"https://github.com/uctb/Urban-Dataset\">a public dataset repository</a> including the following applications:</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\"><strong>Application</strong></th>\n<th align=\"center\"><strong>City</strong></th>\n<th align=\"center\"><strong>Time Range</strong></th>\n<th align=\"center\"><strong>Temporal Granularity</strong></th>\n<th align=\"center\"><strong>Dataset Link</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip\">66.0M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">Chicago</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip\">30.2M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">DC</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip\">31.0M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Pedestrian Count</td>\n<td align=\"center\">Melbourne</td>\n<td align=\"center\">2021.01.01-2022.11.01</td>\n<td align=\"center\">60 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip\">1.18M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Vehicle Speed</td>\n<td align=\"center\">LA</td>\n<td align=\"center\">2012.03.01-2012.06.28</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip\">11.8M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Vehicle Speed</td>\n<td align=\"center\">BAY</td>\n<td align=\"center\">2017.01.01-2017.07.01</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip\">27.9M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Taxi Demand</td>\n<td align=\"center\">Chicago</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip\">6.1M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bus</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2022.02.01-2024.01.13</td>\n<td align=\"center\">60 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip\">4.89M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Metro</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2022.02.01-2023.12.21</td>\n<td align=\"center\">60 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip\">11.3M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Traffic Flow</td>\n<td align=\"center\">Luzern</td>\n<td align=\"center\">2015.01.01-2016.01.01</td>\n<td align=\"center\">3 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Flow/3_minutes/Flow_Luzern.zip\">21M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">Chicago (community)</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip\">6.06</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">Chicago (census tract)</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip\">10M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2009.01.01-2023.06.01</td>\n<td align=\"center\">5 mins</td>\n<td align=\"center\"></td>\n</tr>\n</tbody>\n</table><p>We provide <a class=\"reference external\" href=\"https://github.com/uctb/Urban-Dataset/blob/main/Tutorial/tutorial.ipynb\">detailed documents</a> about how to build and how to use these datasets.</p>\n</div>\n<div class=\"section\" id=\"predictive-tool\">\n<h2>1.2. Predictive Tool<a class=\"headerlink\" href=\"#predictive-tool\" title=\"Permalink to this headline\">¶</a></h2>\n<p>Currently, the package supports the following models: (This toolbox is constructed based on some open-source repos. We appreciate these awesome implements. <a class=\"reference external\" href=\"https://uctb.github.io/UCTB/md_file/static/current_supported_models.html\">See more details</a>).</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th>Model Name</th>\n<th>Input Data Format</th>\n<th>Spatial Modeling Technique</th>\n<th>Graph Type</th>\n<th>Temporal Modeling Technique</th>\n<th>Temporal Knowledge</th>\n<th>Module</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>ARIMA</td>\n<td>Both</td>\n<td>N/A</td>\n<td>N/A</td>\n<td>SARIMA</td>\n<td>Closeness</td>\n<td><code>UCTB.model.ARIMA</code></td>\n</tr>\n<tr>\n<td>HM</td>\n<td>Both</td>\n<td>N/A</td>\n<td>N/A</td>\n<td>N/A</td>\n<td>Closeness</td>\n<td><code>UCTB.model.HM</code></td>\n</tr>\n<tr>\n<td>HMM</td>\n<td>Both</td>\n<td>N/A</td>\n<td>N/A</td>\n<td>HMM</td>\n<td>Closeness</td>\n<td><code>UCTB.model.HMM</code></td>\n</tr>\n<tr>\n<td>XGBoost</td>\n<td>Both</td>\n<td>N/A</td>\n<td>N/A</td>\n<td>XGBoost</td>\n<td>Closeness</td>\n<td><code>UCTB.model.XGBoost</code></td>\n</tr>\n<tr>\n<td>DeepST <a href=\"https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf\">[SIGSPATIAL 2016]</a></td>\n<td>Grid</td>\n<td>CNN</td>\n<td>N/A</td>\n<td>CNN</td>\n<td>Closeness,Period,Trend</td>\n<td><code>UCTB.model.DeepST</code></td>\n</tr>\n<tr>\n<td>ST-ResNet <a href=\"https://arxiv.org/pdf/1610.00081.pdf\">[AAAI 2017]</a></td>\n<td>Grid</td>\n<td>CNN</td>\n<td>N/A</td>\n<td>CNN</td>\n<td>Closeness,Period,Trend</td>\n<td><code>UCTB.model.ST_ResNet</code></td>\n</tr>\n<tr>\n<td>DCRNN  <a href=\"https://arxiv.org/pdf/1707.01926.pdf\">[ICLR 2018]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Prior</strong>(Sensor Network)</td>\n<td>RNN</td>\n<td>Closeness</td>\n<td><code>UCTB.model.DCRNN</code></td>\n</tr>\n<tr>\n<td>GeoMAN  <a href=\"https://www.ijcai.org/proceedings/2018/0476.pdf\">[IJCAI 2018]</a></td>\n<td>Node</td>\n<td>Attention</td>\n<td><strong>Prior</strong>(Sensor Networks)</td>\n<td>Attention+LSTM</td>\n<td>Closeness</td>\n<td><code>UCTB.model.GeoMAN</code></td>\n</tr>\n<tr>\n<td>STGCN  <a href=\"https://www.ijcai.org/proceedings/2018/0505.pdf\">[IJCAI 2018]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Prior</strong>(Traffic Network)</td>\n<td>Gated CNN</td>\n<td>Closeness</td>\n<td><code>UCTB.model.STGCN</code></td>\n</tr>\n<tr>\n<td>GraphWaveNet <a href=\"https://www.ijcai.org/proceedings/2019/0264.pdf\">[IJCAI 2019]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Adaptive</strong></td>\n<td>TCN</td>\n<td>Closeness</td>\n<td><code>UCTB.model.GraphWaveNet</code></td>\n</tr>\n<tr>\n<td>ASTGCN  <a href=\"https://ojs.aaai.org/index.php/AAAI/article/view/3881\">[AAAI 2019]</a></td>\n<td>Node</td>\n<td>GNN+Attention</td>\n<td><strong>Prior</strong>(Traffic Network)</td>\n<td>Attention</td>\n<td>Closeness,Period,Trend</td>\n<td><code>UCTB.model.ASTGCN</code></td>\n</tr>\n<tr>\n<td>ST-MGCN   <a href=\"https://ojs.aaai.org/index.php/AAAI/article/view/4247\">[AAAI 2019]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Prior</strong>(Neighborhood,Functional similarity,Transportation connectivity)</td>\n<td>CGRNN</td>\n<td>Closeness</td>\n<td><code>UCTB.model.ST_MGCN</code></td>\n</tr>\n<tr>\n<td>GMAN  <a href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5477/5333\">[AAAI 2020]</a></td>\n<td>Node</td>\n<td>Attention</td>\n<td><strong>Prior</strong>(Road Network)</td>\n<td>Attention</td>\n<td>Closeness</td>\n<td><code>UCTB.model.GMAN</code></td>\n</tr>\n<tr>\n<td>STSGCN  <a href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5438\">[AAAI 2020]</a></td>\n<td>Node</td>\n<td>GNN+Attention</td>\n<td><strong>Prior</strong>(Spatial Network)</td>\n<td>Attention</td>\n<td>Closeness</td>\n<td><code>UCTB.model.STSGCN</code></td>\n</tr>\n<tr>\n<td>AGCRN <a href=\"https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf\">[NeurIPS 2020]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Adaptive</strong></td>\n<td>RNN</td>\n<td>Closeness</td>\n<td><code>UCTB.model.AGCRN</code></td>\n</tr>\n<tr>\n<td>STMeta <a href=\"https://arxiv.org/abs/2009.09379\">[TKDE 2021]</a></td>\n<td>Node</td>\n<td>GNN</td>\n<td><strong>Prior</strong>(Proximity,Functionality,Interaction/Same-line)</td>\n<td>LSTM/RNN</td>\n<td>Closeness,Period,Trend</td>\n<td><code>UCTB.model.STMeta</code></td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"visualization-tool\">\n<h2>1.3. Visualization Tool<a class=\"headerlink\" href=\"#visualization-tool\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The Visualization tool integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis.</p>\n<p>Welcome to visit the <a class=\"reference external\" href=\"http://39.107.116.221/\">website</a> for a trial!</p>\n<p><u><a class=\"reference external\" href=\"../index.html\">Back To HomePage</a></u></p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"installation.html\" class=\"btn btn-neutral float-right\" title=\"2. Installation\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"../index.html\" class=\"btn btn-neutral\" title=\"Welcome to UCTB’s documentation!\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/predictive_tool.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>4. Predictive Tool &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"5. Visualization-tool\" href=\"visualization_tool.html\"/>\n        <link rel=\"prev\" title=\"3. Urban Datasets\" href=\"urban_dataset.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">4. Predictive Tool</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#currently-supported-models\">4.1. Currently Supported Models</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#agcrn\">4.1.1. AGCRN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#arima\">4.1.2. ARIMA</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#astgcn\">4.1.3. ASTGCN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#dcrnn\">4.1.4. DCRNN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#deepst\">4.1.5. DeepST</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#geoman\">4.1.6. GeoMAN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#gman\">4.1.7. GMAN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#graphwavenet\">4.1.8. GraphWaveNet</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#hm-historical-mean\">4.1.9. HM (Historical Mean)</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#hmm-hidden-markov-model\">4.1.10. HMM (Hidden Markov Model)</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#stgcn\">4.1.11. STGCN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#stmeta\">4.1.12. STMeta</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#st-mgcn\">4.1.13. ST-MGCN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#st-resnet\">4.1.14. ST-ResNet</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#stsgcn\">4.1.15. STSGCN</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#xgboost\">4.1.16. XGBoost</a></li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#quick-start\">4.2. Quick Start</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#quick-start-with-stmeta\">4.2.1. Quick start with STMeta</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#quick-start-with-hm\">4.2.2. Quick Start with HM</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#quick-start-with-arima\">4.2.3. Quick Start with ARIMA</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#quick-start-with-hmm\">4.2.4. Quick Start with HMM</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#quick-start-with-xgboost\">4.2.5. Quick Start with XGBoost</a></li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#tutorial\">4.3. Tutorial</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#load-datasets-from-urban-dataset\">4.3.1. Load datasets from Urban_dataset</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#model-definition-train-test-and-evaluation\">4.3.2. Model definition, train, test and evaluation</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#single-vs-multiple-kinds-of-temporal-knowledge\">4.3.3. Single vs. Multiple kinds of temporal knowledge</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"#use-temporal-closeness-feature-in-regression\">4.3.3.1. Use temporal closeness feature in regression</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"#make-full-use-of-closeness-period-and-trend-features\">4.3.3.2. Make full use of closeness, period, and trend features</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#advanced-features\">4.4. Advanced Features</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#build-your-own-model-using-uctb\">4.4.1. Build your own model using UCTB</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#build-your-own-graph-with-stmeta\">4.4.2. Build your own graph with STMeta</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>4. Predictive Tool</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/predictive_tool.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"predictive-tool\">\n<h1>4. Predictive Tool<a class=\"headerlink\" href=\"#predictive-tool\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"currently-supported-models\">\n<h2>4.1. Currently Supported Models<a class=\"headerlink\" href=\"#currently-supported-models\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"agcrn\">\n<h3>4.1.1. AGCRN<a class=\"headerlink\" href=\"#agcrn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>AGCRN (Adaptive Graph Convolutional Recurrent Network) is a deep nerual network for traffic prediction consisting of two adaptive module and recurrent networks.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf\">Bai, L., Yao, L., Li, C., Wang, X., &amp; Wang, C. (2020). Adaptive graph convolutional recurrent network for traffic forecasting.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/LeiBAI/AGCRN\">Github repository (LeiBAI)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"arima\">\n<h3>4.1.2. ARIMA<a class=\"headerlink\" href=\"#arima\" title=\"Permalink to this headline\">¶</a></h3>\n<p>ARIMA (Autoregressive Integrated Moving Average) is a widely used classical statistical model on time series prediction.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www3.nd.edu/%7Ebusiforc/handouts/ARIMA%20Engineering%20Article.pdf\">Williams, B. M., &amp; Hoel, L. A. (2003). Modeling and forecasting vehicular traffic flow as a seasonal ARIMA process: Theoretical basis and empirical results</a></li>\n</ul>\n</li>\n<li>Reference Package: <code class=\"docutils literal\"><span class=\"pre\">pandas</span></code>, <code class=\"docutils literal\"><span class=\"pre\">statsmodels</span></code></li>\n</ul>\n</div>\n<div class=\"section\" id=\"astgcn\">\n<h3>4.1.3. ASTGCN<a class=\"headerlink\" href=\"#astgcn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>ASTGCN (Attenion Based Spatial-temporal Graph Convolutional Networks) is a deep neural network for traffic flow forecasting. It models temporal-dependencies from three perspectives using attetion mechanism. And it models spatial-dependencies employing graph convolutions.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/3881\">Guo, S., Lin, Y., Feng, N., Song, C., &amp; Wan, H. (2019, July). Attention based spatial-temporal graph convolutional networks for traffic flow forecasting.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/guoshnBJTU/ASTGCN-r-pytorch\">Github repository (guoshnBJTU)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"dcrnn\">\n<h3>4.1.4. DCRNN<a class=\"headerlink\" href=\"#dcrnn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>DCRNN (Diffusion Convolutional Recurrent Neural Network) is a deep learning framework for traffic forecasting that incorporates both spatial and temporal dependency in the traffic flow. It captures the spatial dependency using bidirectional random walks on the graph, and the temporal dependency using the encoder-decoder architecture with scheduled sampling.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://arxiv.org/abs/1707.01926\">Li, Y., Yu, R., Shahabi, C., &amp; Liu, Y. (2017). Diffusion convolutional recurrent neural network: Data-driven traffic forecasting</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/liyaguang/DCRNN\">A TensorFlow implementation of Diffusion Convolutional Recurrent Neural Network (liyaguang)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"deepst\">\n<h3>4.1.5. DeepST<a class=\"headerlink\" href=\"#deepst\" title=\"Permalink to this headline\">¶</a></h3>\n<p>DeepST (Deep learning-based prediction model for Spatial-Temporal data) is composed of three components: 1) temporal dependent instances: describing temporal closeness, period and seasonal trend; 2) convolutional neural networks: capturing near and far spatial dependencies; 3) early and late fusions: fusing similar and different domains' data.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf\">Zhang, J., Zheng, Y., Qi, D., Li, R., &amp; Yi, X. (2016, October). DNN-based prediction model for spatio-temporal data</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"geoman\">\n<h3>4.1.6. GeoMAN<a class=\"headerlink\" href=\"#geoman\" title=\"Permalink to this headline\">¶</a></h3>\n<p>GeoMAN (Multi-level Attention Networks for Geo-sensory Time Series Prediction) consists of two major parts: 1) A multi-level attention mechanism (including both local and global  spatial attentions in encoder and temporal attention in decoder) to model the dynamic spatio-temporal  dependencies; 2) A general fusion module to incorporate the external factors from different domains (e.g.,  meteorology, time of day and land use).</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2018/0476.pdf\">Liang, Y., Ke, S., Zhang, J., Yi, X., &amp; Zheng, Y. (2018, July). GeoMAN: Multi-level Attention Networks for Geo-sensory Time Series Prediction</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/yoshall/GeoMAN\">An easy implement of GeoMAN using TensorFlow (yoshall &amp; CastleLiang)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"gman\">\n<h3>4.1.7. GMAN<a class=\"headerlink\" href=\"#gman\" title=\"Permalink to this headline\">¶</a></h3>\n<p>GMAN (Graph Multi-Attention Network) is a deep nerual network for traffic prediction adopting encoder-decoder architecture. Both encode and decoder consist of multiple spatio-temporal attention blocks to model spatio-temporal dependencies.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5477\">Zheng, C., Fan, X., Wang, C., &amp; Qi, J. (2020, April). Gman: A graph multi-attention network for traffic prediction.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/zhengchuanpan/GMAN\">implementation of Graph Multi-Attention Network</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"graphwavenet\">\n<h3>4.1.8. GraphWaveNet<a class=\"headerlink\" href=\"#graphwavenet\" title=\"Permalink to this headline\">¶</a></h3>\n<p>GraphWaveNet is an end-to-end novel graph neural network. It captures spatial dependencies through a self-adptive adjacency matrix. And it captures temporal dependencies through convolutions.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2019/0264.pdf\">Wu, Z., Pan, S., Long, G., Jiang, J., &amp; Zhang, C. (2019). Graph wavenet for deep spatial-temporal graph modeling.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/nnzhan/Graph-WaveNet\">Github repository (nnzhan)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"hm-historical-mean\">\n<h3>4.1.9. HM (Historical Mean)<a class=\"headerlink\" href=\"#hm-historical-mean\" title=\"Permalink to this headline\">¶</a></h3>\n<p>HM is a constant model and always forecasts the sample mean of the historical data.</p>\n</div>\n<div class=\"section\" id=\"hmm-hidden-markov-model\">\n<h3>4.1.10. HMM (Hidden Markov Model)<a class=\"headerlink\" href=\"#hmm-hidden-markov-model\" title=\"Permalink to this headline\">¶</a></h3>\n<p>Hidden Markov Model is a statistical Markov model in which the system being modeled is assumed to be a Markov process with hidden states. It is often used in temporal pattern recognition.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://ieeexplore.ieee.org/abstract/document/7785328\">Chen, Z., Wen, J., &amp; Geng, Y. (2016, November). Predicting future traffic using hidden markov models</a></li>\n</ul>\n</li>\n<li>Reference Package: <code class=\"docutils literal\"><span class=\"pre\">hmmlearn</span></code></li>\n</ul>\n</div>\n<div class=\"section\" id=\"stgcn\">\n<h3>4.1.11. STGCN<a class=\"headerlink\" href=\"#stgcn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>STGCN (Spatio-temporal Graph Convolutional Networks) is a deep learning framework for traffic forecasting with complete convolutional structures.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www.ijcai.org/proceedings/2018/0505.pdf\">Yu, B., Yin, H., &amp; Zhu, Z. (2017). Spatio-temporal graph convolutional networks: A deep learning framework for traffic forecasting.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/VeritasYin/STGCN_IJCAI-18\">Github repository (VeritasYin)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"stmeta\">\n<h3>4.1.12. STMeta<a class=\"headerlink\" href=\"#stmeta\" title=\"Permalink to this headline\">¶</a></h3>\n<p>STMeta is our prediction model, which requires extra graph information as input, and combines Graph Convolution LSTM and Attention mechanism.</p>\n<ul class=\"simple\">\n<li>Reference Package: <code class=\"docutils literal\"><span class=\"pre\">tensorflow</span></code></li>\n</ul>\n</div>\n<div class=\"section\" id=\"st-mgcn\">\n<h3>4.1.13. ST-MGCN<a class=\"headerlink\" href=\"#st-mgcn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>ST-MGCN (Spatiotemporal Multi-graph Convolution Network) is a deep learning based model which encoded the non-Euclidean correlations among regions using multiple graphs and explicitly captured them using multi-graph convolution.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://ieeexplore.ieee.org/abstract/document/7785328\">Geng, X., Li, Y., Wang, L., Zhang, L., Yang, Q., Ye, J., &amp; Liu, Y. (2019). Spatiotemporal multi-graph convolution network for ride-hailing demand forecasting</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/shawnwang-tech/ST-MGCN-pytorch\">A PyTorch implementation of the ST-MGCN model  (shawnwang-tech)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"st-resnet\">\n<h3>4.1.14. ST-ResNet<a class=\"headerlink\" href=\"#st-resnet\" title=\"Permalink to this headline\">¶</a></h3>\n<p>ST-ResNet is a deep-learning model with an end-to-end structure based on unique properties of spatio-temporal data making use of convolution and residual units.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://arxiv.org/pdf/1610.00081.pdf\">Zhang, J., Zheng, Y., &amp; Qi, D. (2017, February). Deep spatio-temporal residual networks for citywide crowd flows prediction</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/lucktroy/DeepST/tree/master/scripts/papers/AAAI17\">Github repository (lucktroy)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"stsgcn\">\n<h3>4.1.15. STSGCN<a class=\"headerlink\" href=\"#stsgcn\" title=\"Permalink to this headline\">¶</a></h3>\n<p>STSGCN (Spatial-temporal Synchronous Graph Convolutional Networks) is a deep learning framework for spatial-temporal network data forecasting. It is able to capture spatial-temporal dependencies through a designed spatial-temporal synchronous modeling mechanism.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://ojs.aaai.org/index.php/AAAI/article/view/5438\">Song, C., Lin, Y., Guo, S., &amp; Wan, H. (2020, April). Spatial-temporal synchronous graph convolutional networks: A new framework for spatial-temporal network data forecasting.</a></li>\n</ul>\n</li>\n<li>Reference Implementation:<ul>\n<li><a class=\"reference external\" href=\"https://github.com/Davidham3/STSGCN\">Github repository (Davidham3)</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"section\" id=\"xgboost\">\n<h3>4.1.16. XGBoost<a class=\"headerlink\" href=\"#xgboost\" title=\"Permalink to this headline\">¶</a></h3>\n<p>XGBoost is a gradient boosting machine learning algorithm widely used in flow prediction and other machine learning prediction areas.</p>\n<ul class=\"simple\">\n<li>Reference Paper:<ul>\n<li><a class=\"reference external\" href=\"https://www.mdpi.com/2073-8994/10/9/386\">Alajali, W., Zhou, W., Wen, S., &amp; Wang, Y. (2018). Intersection Traffic Prediction Using Decision Tree Models</a></li>\n</ul>\n</li>\n<li>Reference Package: <code class=\"docutils literal\"><span class=\"pre\">xgboost</span></code></li>\n</ul>\n</div>\n</div>\n<div class=\"section\" id=\"quick-start\">\n<h2>4.2. Quick Start<a class=\"headerlink\" href=\"#quick-start\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"quick-start-with-stmeta\">\n<h3>4.2.1. Quick start with STMeta<a class=\"headerlink\" href=\"#quick-start-with-stmeta\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">STMeta</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.preprocess.GraphGenerator</span> <span class=\"kn\">import</span> <span class=\"n\">GraphGenerator</span>\n<span class=\"c1\"># Config data loader</span>\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span> <span class=\"n\">graph</span><span class=\"o\">=</span><span class=\"s1\">&#39;Correlation&#39;</span><span class=\"p\">,</span>\n                                <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Build Graph</span>\n<span class=\"n\">graph_obj</span> <span class=\"o\">=</span> <span class=\"n\">GraphGenerator</span><span class=\"p\">(</span><span class=\"n\">graph</span><span class=\"o\">=</span><span class=\"s1\">&#39;Correlation&#39;</span><span class=\"p\">,</span> <span class=\"n\">data_loader</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Init model object</span>\n<span class=\"n\">STMeta_Obj</span> <span class=\"o\">=</span> <span class=\"n\">STMeta</span><span class=\"p\">(</span><span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span><span class=\"p\">,</span>\n                    <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">period_len</span><span class=\"p\">,</span>\n                    <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">trend_len</span><span class=\"p\">,</span>\n                    <span class=\"n\">num_node</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">,</span>\n                    <span class=\"n\">num_graph</span><span class=\"o\">=</span><span class=\"n\">graph_obj</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span>\n                    <span class=\"n\">external_dim</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">external_dim</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Build tf-graph</span>\n<span class=\"n\">STMeta_Obj</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">()</span>\n<span class=\"c1\"># Training</span>\n<span class=\"n\">STMeta_Obj</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">closeness_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">,</span>\n               <span class=\"n\">period_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">,</span>\n               <span class=\"n\">trend_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">,</span>\n               <span class=\"n\">laplace_matrix</span><span class=\"o\">=</span><span class=\"n\">graph_obj</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"p\">,</span>\n               <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">,</span>\n               <span class=\"n\">external_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_ef</span><span class=\"p\">,</span>\n               <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_sequence_len</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Predict</span>\n<span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"n\">STMeta_Obj</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">closeness_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span>\n                                <span class=\"n\">period_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">,</span>\n                                <span class=\"n\">trend_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">,</span>\n                                <span class=\"n\">laplace_matrix</span><span class=\"o\">=</span><span class=\"n\">graph_obj</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"p\">,</span>\n                                <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">,</span>\n                                <span class=\"n\">external_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_ef</span><span class=\"p\">,</span>\n                                <span class=\"n\">output_names</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">],</span>\n                                <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_sequence_len</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Evaluate</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Test result&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_denormal</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]),</span>\n                                 <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_denormal</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">)))</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"quick-start-with-hm\">\n<h3>4.2.2. Quick Start with HM<a class=\"headerlink\" href=\"#quick-start-with-hm\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">HM</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span> <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n                                <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n<span class=\"n\">hm_obj</span> <span class=\"o\">=</span> <span class=\"n\">HM</span><span class=\"p\">(</span><span class=\"n\">c</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">closeness_len</span><span class=\"p\">,</span> <span class=\"n\">p</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">period_len</span><span class=\"p\">,</span> <span class=\"n\">t</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">trend_len</span><span class=\"p\">)</span>\n\n<span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"n\">hm_obj</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">closeness_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span>\n                            <span class=\"n\">period_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">,</span>\n                            <span class=\"n\">trend_feature</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">)</span>\n\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;RMSE&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">,</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">))</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"quick-start-with-arima\">\n<h3>4.2.3. Quick Start with ARIMA<a class=\"headerlink\" href=\"#quick-start-with-arima\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">ARIMA</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span> <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">24</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n                                <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n<span class=\"n\">test_prediction_collector</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n<span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"n\">model_obj</span> <span class=\"o\">=</span> <span class=\"n\">ARIMA</span><span class=\"p\">(</span><span class=\"n\">time_sequence</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                          <span class=\"n\">order</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">seasonal_order</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n        <span class=\"n\">test_prediction</span> <span class=\"o\">=</span> <span class=\"n\">model_obj</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">time_sequences</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                                            <span class=\"n\">forecast_step</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"k\">except</span> <span class=\"ne\">Exception</span> <span class=\"k\">as</span> <span class=\"n\">e</span><span class=\"p\">:</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Converge failed with error&#39;</span><span class=\"p\">,</span> <span class=\"n\">e</span><span class=\"p\">)</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Using last as prediction&#39;</span><span class=\"p\">)</span>\n        <span class=\"n\">test_prediction</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:,</span> <span class=\"p\">:]</span>\n    <span class=\"n\">test_prediction_collector</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">test_prediction</span><span class=\"p\">)</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Station&#39;</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"s1\">&#39;finished&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">test_rmse</span> <span class=\"o\">=</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">(</span><span class=\"n\">test_prediction_collector</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">)</span>\n\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;test_rmse&#39;</span><span class=\"p\">,</span> <span class=\"n\">test_rmse</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"quick-start-with-hmm\">\n<h3>4.2.4. Quick Start with HMM<a class=\"headerlink\" href=\"#quick-start-with-hmm\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">HMM</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span>\n                                <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n                                <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n<span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n<span class=\"k\">for</span> <span class=\"n\">station_index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">):</span>\n    <span class=\"c1\"># train the hmm model</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"n\">hmm</span> <span class=\"o\">=</span> <span class=\"n\">HMM</span><span class=\"p\">(</span><span class=\"n\">num_components</span><span class=\"o\">=</span><span class=\"mi\">8</span><span class=\"p\">,</span> <span class=\"n\">n_iter</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n        <span class=\"n\">hmm</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">station_index</span><span class=\"p\">:</span><span class=\"n\">station_index</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n        <span class=\"c1\"># predict</span>\n        <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n        <span class=\"k\">for</span> <span class=\"n\">time_index</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]):</span>\n            <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">hmm</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[</span><span class=\"n\">time_index</span><span class=\"p\">,</span> <span class=\"n\">station_index</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"p\">:],</span> <span class=\"n\">length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n    <span class=\"k\">except</span> <span class=\"ne\">Exception</span> <span class=\"k\">as</span> <span class=\"n\">e</span><span class=\"p\">:</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Failed at station&#39;</span><span class=\"p\">,</span> <span class=\"n\">station_index</span><span class=\"p\">,</span> <span class=\"s1\">&#39;with error&#39;</span><span class=\"p\">,</span> <span class=\"n\">e</span><span class=\"p\">)</span>\n        <span class=\"c1\"># using zero as prediction</span>\n        <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"p\">[[[</span><span class=\"mi\">0</span><span class=\"p\">]]</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])]</span>\n\n    <span class=\"n\">prediction</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">p</span><span class=\"p\">)[:,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">,</span> <span class=\"n\">station_index</span><span class=\"p\">,</span> <span class=\"s1\">&#39;finished&#39;</span><span class=\"p\">)</span>\n\n<span class=\"n\">prediction</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">transpose</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">])</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;RMSE&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"p\">,</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">))</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"quick-start-with-xgboost\">\n<h3>4.2.5. Quick Start with XGBoost<a class=\"headerlink\" href=\"#quick-start-with-xgboost\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">XGBoost</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span> <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span>\n                                <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n<span class=\"n\">prediction_test</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n<span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">):</span>\n\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;*************************************************************&#39;</span><span class=\"p\">)</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Station&#39;</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">)</span>\n\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">XGBoost</span><span class=\"p\">(</span><span class=\"n\">n_estimators</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"n\">max_depth</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">objective</span><span class=\"o\">=</span><span class=\"s1\">&#39;reg:squarederror&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span>\n              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n\n    <span class=\"n\">p_test</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                                           <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                                           <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n\n    <span class=\"n\">prediction_test</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">p_test</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]))</span>\n\n<span class=\"n\">prediction_test</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">(</span><span class=\"n\">prediction_test</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Test RMSE&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction_test</span><span class=\"p\">,</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">))</span>\n</pre></div>\n</div>\n</div>\n</div>\n<div class=\"section\" id=\"tutorial\">\n<h2>4.3. Tutorial<a class=\"headerlink\" href=\"#tutorial\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The general process of completing a spatiotemporal prediction task includes: loading dataset, defining model, training, testing, model evaluation.</p>\n<p><img alt=\"tutorial\" src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/tutorial.png\" /></p>\n<div class=\"section\" id=\"load-datasets-from-urban-dataset\">\n<h3>4.3.1. Load datasets from Urban_dataset<a class=\"headerlink\" href=\"#load-datasets-from-urban-dataset\" title=\"Permalink to this headline\">¶</a></h3>\n<p>To help better accuse dataset, UCTB provides data loader APIs <code class=\"docutils literal\"><span class=\"pre\">UCTB.dataset.data_loader</span></code>, which can be used to preprocess data, including <strong>data division</strong>, <strong>normalization</strong>, and <strong>extract temporal and spatial knowledge</strong>.</p>\n<p>In the following tutorial, we will illustrate how to use <code class=\"docutils literal\"><span class=\"pre\">UCTB.dataset.data_loader</span></code> APIs to inspect the speed dataset.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset.data_loader</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n</pre></div>\n</div>\n<p>We use all(data_range='all') of speed data in METR_LA(Assume that scripts are put under root directory, METR_LA dataset is put under <code class=\"docutils literal\"><span class=\"pre\">./data</span></code> directory.). Firstly, let's initialize a NodeTrafficLoader object:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;LA&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">data_range</span><span class=\"o\">=</span><span class=\"s1\">&#39;all&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">train_data_length</span><span class=\"o\">=</span><span class=\"s1\">&#39;all&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">test_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span>\n                 <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span>\n                 <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">,</span>\n                 <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span>\n                 <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span>\n                 <span class=\"n\">data_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;data&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">MergeIndex</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                 <span class=\"n\">MergeWay</span><span class=\"o\">=</span><span class=\"s2\">&quot;sum&quot;</span><span class=\"p\">,</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;METR&#39;</span><span class=\"p\">,</span><span class=\"n\">remove</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>NodeTrafficLoader is the base class for dataset extracting and processing. Input arguments appeared in constructor above will be explained.</p>\n<ul class=\"simple\">\n<li>data range selection\n<code class=\"docutils literal\"><span class=\"pre\">*data</span> <span class=\"pre\">range</span> <span class=\"pre\">=</span> <span class=\"pre\">'all'</span></code> means that we choose the whole data as our traffic_data to train, test, and predict.</li>\n<li>data spliting(train set and test set spliting)</li>\n</ul>\n<p><code class=\"docutils literal\"><span class=\"pre\">train_data</span> <span class=\"pre\">length</span> <span class=\"pre\">=</span> <span class=\"pre\">'all'</span></code> means that we exploit all of the traffic_data. <code class=\"docutils literal\"><span class=\"pre\">'train_test_ratio</span> <span class=\"pre\">=</span> <span class=\"pre\">0.1</span></code> means we divide the dataset into train and test sets. And the train set to the test set is nine to one.</p>\n<ul class=\"simple\">\n<li>normalization</li>\n</ul>\n<p><code class=\"docutils literal\"><span class=\"pre\">normalization</span> <span class=\"pre\">=</span> <span class=\"pre\">False</span></code> means that we normalized the dataset through min-max-normalization method. When we input False, we simply do not employ any preprocessing tricks on the dataset.</p>\n<ul class=\"simple\">\n<li>data merging</li>\n</ul>\n<p><code class=\"docutils literal\"><span class=\"pre\">MergeIndex</span> <span class=\"pre\">=</span> <span class=\"pre\">1,</span> <span class=\"pre\">MergeWay</span> <span class=\"pre\">=</span> <span class=\"pre\">'sum'</span></code> means that granularity of raw dataset will not be changed. If we try MergeIndex &gt; 1, we can obtain combination of MergeIndex time slots of data in a way of 'sum' or 'average'.</p>\n<ul class=\"simple\">\n<li>multiple time series building(temporal knowledge exploiting)</li>\n</ul>\n<p><code class=\"docutils literal\"><span class=\"pre\">closeness_len</span> <span class=\"pre\">=</span> <span class=\"pre\">6,</span> <span class=\"pre\">period_len=7,</span> <span class=\"pre\">trend_len=4,</span> <span class=\"pre\">target_length=1</span></code> means that we create 3 time series, using former consecutive closeness_len time slots of data as a unit, former every other daily_slots time slots of data as a unit(consisting of period_len piece of data), former every other daily_slots*7 time slots of data as a unit(consisting of trend_len piece of data) respectively.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_data</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">30844</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>You may probably note that the length of train_closeness is 13778 less than that of train_data. It's because we choose the shortest data length among the three series(train_trend) for alignment.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/data_reassemble.png\" style=\"zoom: 10%;\" /><p>Above is the visualization of a new time series's construction. In this situation, feature_stride = 3(means sampling interval), feature_step = 3(means how many times we sample).Other time series are just the same situation.</p>\n<p>Through the process in the figure shown above, we can calculate the length of train_trend is $30844-12<em>24</em>7*4=22780$, which is the minimum among three time series.</p>\n<p><strong>Operations</strong></p>\n<ul class=\"simple\">\n<li>Denormalization/Normalization</li>\n<li>Visualization</li>\n<li>Temporal Knowledge Exploitation</li>\n<li>Spatial knowledge Exploration</li>\n<li>Access to raw data</li>\n</ul>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">matplotlib.pyplot</span> <span class=\"k\">as</span> <span class=\"nn\">plt</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.preprocess.preprocessor</span> <span class=\"kn\">import</span> <span class=\"n\">Normalizer</span>\n\n<span class=\"c1\"># without normalization</span>\n\n<span class=\"n\">target_node</span> <span class=\"o\">=</span> <span class=\"mi\">5</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"p\">[:,</span><span class=\"mi\">5</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">title</span><span class=\"p\">(</span><span class=\"s1\">&#39;Raw&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n\n<span class=\"c1\"># normalization</span>\n\n<span class=\"n\">normalizer</span><span class=\"o\">=</span><span class=\"n\">Normalizer</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"p\">)</span>\n<span class=\"n\">X_normalized</span> <span class=\"o\">=</span> <span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_normal</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># denormalization</span>\n\n<span class=\"n\">X_denormalized</span> <span class=\"o\">=</span> <span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_denormal</span><span class=\"p\">(</span><span class=\"n\">X_normalized</span><span class=\"p\">)</span>\n\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">X_normalized</span><span class=\"p\">[:,</span><span class=\"mi\">5</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">title</span><span class=\"p\">(</span><span class=\"s1\">&#39;Normalized&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">X_denormalized</span><span class=\"p\">[:,</span><span class=\"mi\">5</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">title</span><span class=\"p\">(</span><span class=\"s1\">&#39;Denormalized&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n</pre></div>\n</div>\n<p><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Raw_data.png\" alt=\"Raw_data\" style=\"zoom:33%;\" /><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/normalized_data.png\" style=\"zoom:33%;\" /><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/denormalized_data.png\" style=\"zoom:33%;\" /></p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># Nodes&#39; location visualizations</span>\n<span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">st_map</span><span class=\"p\">()</span>\n</pre></div>\n</div>\n<p>Visualization result is as follows:</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/METR_LA.png\" alt=\"Node location of METR_LA\" style=\"zoom: 50%;\" /><div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># data visualization</span>\n<span class=\"kn\">import</span> <span class=\"nn\">seaborn</span> <span class=\"k\">as</span> <span class=\"nn\">sns</span>\n<span class=\"kn\">import</span> <span class=\"nn\">matplotlib.pyplot</span> <span class=\"k\">as</span> <span class=\"nn\">plt</span>\n<span class=\"n\">real_denormed</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">min_max_denormal</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">)</span>\n<span class=\"n\">sns</span><span class=\"o\">.</span><span class=\"n\">heatmap</span><span class=\"p\">(</span><span class=\"n\">real_denormed</span><span class=\"p\">[:,:,</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">cmap</span><span class=\"o\">=</span><span class=\"s1\">&#39;Reds&#39;</span><span class=\"p\">,</span> <span class=\"n\">vmin</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1000</span><span class=\"p\">,</span> <span class=\"n\">vmax</span> <span class=\"o\">=</span> <span class=\"mi\">4000</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">ylabel</span><span class=\"p\">(</span><span class=\"s2\">&quot;Time Slot&quot;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">xlabel</span><span class=\"p\">(</span><span class=\"s2\">&quot;Sensor Node&quot;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">title</span><span class=\"p\">(</span><span class=\"s2\">&quot;Visualization&quot;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># Feature stitching</span>\n<span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">make_concat</span><span class=\"p\">()</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;before concatenate&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;closeness&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;period&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;trend&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;After concatenate&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"n\">before</span> <span class=\"n\">concatenate</span>\n<span class=\"n\">closeness</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">period</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">trend</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">After</span> <span class=\"n\">concatenate</span>\n<span class=\"p\">(</span><span class=\"mi\">22780</span><span class=\"p\">,</span> <span class=\"mi\">207</span><span class=\"p\">,</span> <span class=\"mi\">17</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># access to raw data</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">traffic_data</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">])</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"mf\">64.375</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"model-definition-train-test-and-evaluation\">\n<h3>4.3.2. Model definition, train, test and evaluation<a class=\"headerlink\" href=\"#model-definition-train-test-and-evaluation\" title=\"Permalink to this headline\">¶</a></h3>\n<p>We use XGBoost interface in UCTB as an example to define a model. Since there are total 207 stations in METR_LA dataset, we define 207 XGBoost models respectively. They are trained and tested in their own iteration related to stations. Finally, when we evaluate our model, we consider the prediction results as a whole and evaluate it against GroundTruth provided by <code class=\"docutils literal\"><span class=\"pre\">data_loader</span></code> using <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Root-mean-square_deviation\">RMSE</a> metric.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">XGBoost</span>\n<span class=\"kn\">import</span> <span class=\"nn\">UCTB.evaluation.metric</span> <span class=\"k\">as</span> <span class=\"nn\">metric</span>\n<span class=\"n\">prediction_test</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n<span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">):</span>\n\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;*************************************************************&#39;</span><span class=\"p\">)</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Station&#39;</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">)</span>\n\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">XGBoost</span><span class=\"p\">(</span><span class=\"n\">n_estimators</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"n\">max_depth</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">objective</span><span class=\"o\">=</span><span class=\"s1\">&#39;reg:squarederror&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">),</span>\n              <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n\n    <span class=\"n\">p_test</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">((</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                                           <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n                                           <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">[:,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],),</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">))</span>\n\n    <span class=\"n\">prediction_test</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">p_test</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">]))</span>\n\n<span class=\"n\">prediction_test</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">(</span><span class=\"n\">prediction_test</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n\n<span class=\"n\">y_truth</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">inverse_transform</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">)</span>\n<span class=\"n\">y_pred</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">inverse_transform</span><span class=\"p\">(</span><span class=\"n\">prediction_test</span><span class=\"p\">)</span>\n<span class=\"n\">y_truth</span> <span class=\"o\">=</span> <span class=\"n\">y_truth</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">207</span><span class=\"p\">])</span>\n<span class=\"n\">y_pred</span> <span class=\"o\">=</span> <span class=\"n\">y_pred</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">207</span><span class=\"p\">])</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Test RMSE&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">y_pred</span><span class=\"p\">,</span> <span class=\"n\">y_truth</span><span class=\"p\">))</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">title</span><span class=\"p\">(</span><span class=\"s1\">&#39;XGBoost Result&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">xlabel</span><span class=\"p\">(</span><span class=\"s1\">&#39;Time Slot&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">ylabel</span><span class=\"p\">(</span><span class=\"s1\">&#39;Speed&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">y_pred</span><span class=\"p\">[:</span><span class=\"mi\">12</span><span class=\"o\">*</span><span class=\"mi\">24</span><span class=\"o\">*</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"n\">target_node</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">y_truth</span><span class=\"p\">[:</span><span class=\"mi\">12</span><span class=\"o\">*</span><span class=\"mi\">24</span><span class=\"o\">*</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"n\">target_node</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">legend</span><span class=\"p\">([</span><span class=\"s1\">&#39;gt&#39;</span><span class=\"p\">,</span><span class=\"s1\">&#39;pred&#39;</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n</pre></div>\n</div>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/XGBoost_Result.png\" alt=\"XGBoost Result\" style=\"zoom:50%;\" /><div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"n\">Test</span> <span class=\"n\">RMSE</span> <span class=\"mf\">5.549781682961724</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"single-vs-multiple-kinds-of-temporal-knowledge\">\n<h3>4.3.3. Single vs. Multiple kinds of temporal knowledge<a class=\"headerlink\" href=\"#single-vs-multiple-kinds-of-temporal-knowledge\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"section\" id=\"use-temporal-closeness-feature-in-regression\">\n<h4>4.3.3.1. Use temporal closeness feature in regression<a class=\"headerlink\" href=\"#use-temporal-closeness-feature-in-regression\" title=\"Permalink to this headline\">¶</a></h4>\n<p>UCTB provides many classical and popular spatial-temporal predicting models. These models can be used to either predicting series for a single station or all stations. You can find the details in <a class=\"reference external\" href=\"./static/current_supported_models.html\"><code class=\"docutils literal\"><span class=\"pre\">UCTB.model</span></code></a>.</p>\n<p>The following example shows how to use a <strong>XGBoost</strong> model to handle a simple time series predicting a problem. We will try to predict the bike demands <code class=\"docutils literal\"><span class=\"pre\">test_y</span></code> of a fixed station <code class=\"docutils literal\"><span class=\"pre\">target_node</span></code> in New York City by checking back the historical demands in recent time slots <code class=\"docutils literal\"><span class=\"pre\">train_closeness</span></code>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">matplotlib.pyplot</span> <span class=\"k\">as</span> <span class=\"nn\">plt</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">XGBoost</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n<span class=\"n\">target_node</span> <span class=\"o\">=</span> <span class=\"mi\">233</span>\n</pre></div>\n</div>\n<p>When initializing the loader, we use past <code class=\"docutils literal\"><span class=\"pre\">12</span></code> time slots (timesteps) of closeness as input, <code class=\"docutils literal\"><span class=\"pre\">1</span></code> timestep in the next as output and set the timesteps of other features <code class=\"docutils literal\"><span class=\"pre\">period_len</span></code>, <code class=\"docutils literal\"><span class=\"pre\">period_len</span></code> to zero.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span> <span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span>\n                                <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n                                <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">test_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.2</span><span class=\"p\">,</span> \n                                <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">with_tpe</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>The well-loaded data contain all <code class=\"docutils literal\"><span class=\"pre\">717</span></code> stations' data. Therefore it is needed to specify the target station by <code class=\"docutils literal\"><span class=\"pre\">target_station</span></code>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"p\">(</span><span class=\"mi\">2967</span><span class=\"p\">,</span> <span class=\"mi\">717</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,</span> <span class=\"mi\">717</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,</span> <span class=\"mi\">717</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">train_x</span><span class=\"p\">,</span> <span class=\"n\">test_x</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">train_y</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">test_y</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n</pre></div>\n</div>\n<p>Inspect the shape of data. Here are the all we need for one-station prediction.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">train_x</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">train_y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">test_x</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">test_y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"p\">(</span><span class=\"mi\">2967</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">2967</span><span class=\"p\">,)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,)</span>\n</pre></div>\n</div>\n<p>Build the XGBoost model.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">XGBoost</span><span class=\"p\">(</span><span class=\"n\">n_estimators</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"n\">max_depth</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">objective</span><span class=\"o\">=</span><span class=\"s1\">&#39;reg:linear&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Now, we can fit the model with the train dataset and make predictions on the test dataset.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"o\">=</span><span class=\"n\">train_x</span><span class=\"p\">)</span>\n<span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">test_x</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>We can evaluate the performance of the model by build-in <code class=\"docutils literal\"><span class=\"pre\">UCTB.evaluation</span></code> APIs.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">test_rmse</span> <span class=\"o\">=</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">predictions</span><span class=\"p\">,</span> <span class=\"n\">test_y</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">test_rmse</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"mf\">3.6033132</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"make-full-use-of-closeness-period-and-trend-features\">\n<h4>4.3.3.2. Make full use of closeness, period, and trend features<a class=\"headerlink\" href=\"#make-full-use-of-closeness-period-and-trend-features\" title=\"Permalink to this headline\">¶</a></h4>\n<p>In this case, let's take more temporal knowledge related to <code class=\"docutils literal\"><span class=\"pre\">target_node</span></code> into account. We will concatenate factors including <code class=\"docutils literal\"><span class=\"pre\">closeness</span></code>, <code class=\"docutils literal\"><span class=\"pre\">period</span></code>, and <code class=\"docutils literal\"><span class=\"pre\">trend</span></code>, and use <strong>XGBoost</strong> as the predicting model.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">matplotlib.pyplot</span> <span class=\"k\">as</span> <span class=\"nn\">plt</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model</span> <span class=\"kn\">import</span> <span class=\"n\">XGBoost</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n\n<span class=\"n\">target_node</span> <span class=\"o\">=</span> <span class=\"mi\">233</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span> <span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span>\n                                <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">,</span>\n                                <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">test_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.2</span><span class=\"p\">,</span> \n                                <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">with_tpe</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n<span class=\"n\">train_closeness</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">train_period</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_period</span><span class=\"p\">[:,</span> <span class=\"n\">target_nodze</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">train_trend</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_trend</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">train_y</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n\n<span class=\"n\">test_closeness</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">test_period</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_period</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">test_trend</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_trend</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"n\">test_y</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">[:,</span> <span class=\"n\">target_node</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">]</span>\n\n<span class=\"n\">train_X</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">([</span><span class=\"n\">train_closeness</span><span class=\"p\">,</span> <span class=\"n\">train_period</span><span class=\"p\">,</span> <span class=\"n\">train_trend</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">test_X</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">([</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span> <span class=\"n\">test_period</span><span class=\"p\">,</span> <span class=\"n\">test_trend</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">train_X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">train_y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">test_X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">test_y</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span>\n\n<span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">XGBoost</span><span class=\"p\">(</span><span class=\"n\">n_estimators</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"n\">max_depth</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">objective</span><span class=\"o\">=</span><span class=\"s1\">&#39;reg:linear&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">train_X</span><span class=\"p\">,</span> <span class=\"n\">train_y</span><span class=\"p\">)</span>\n<span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">test_X</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Test RMSE&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">predictions</span><span class=\"p\">,</span> <span class=\"n\">test_y</span><span class=\"p\">))</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"p\">(</span><span class=\"mi\">2307</span><span class=\"p\">,</span> <span class=\"mi\">17</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">2307</span><span class=\"p\">,)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,</span> <span class=\"mi\">17</span><span class=\"p\">)</span>\n<span class=\"p\">(</span><span class=\"mi\">745</span><span class=\"p\">,)</span>\n<span class=\"n\">Test</span> <span class=\"n\">RMSE</span> <span class=\"mf\">3.3267457</span>\n</pre></div>\n</div>\n</div>\n</div>\n</div>\n<div class=\"section\" id=\"advanced-features\">\n<h2>4.4. Advanced Features<a class=\"headerlink\" href=\"#advanced-features\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"build-your-own-model-using-uctb\">\n<h3>4.4.1. Build your own model using UCTB<a class=\"headerlink\" href=\"#build-your-own-model-using-uctb\" title=\"Permalink to this headline\">¶</a></h3>\n<p>UCTB provides extendable APIs to build your own model. Currently, it can support the running of all the <code class=\"docutils literal\"><span class=\"pre\">1.x</span></code> version of <strong>Tensorflow-based</strong> models. In the following tutorial, we will show you how to takes the least efforts to implement a UCTB model.</p>\n<p>Commonly, a new model needs to inherit <code class=\"docutils literal\"><span class=\"pre\">BaseModel</span></code> to acquire the features provided by UCTB, such as batch division, early stopping, etc. The necessary components for a subclass of <code class=\"docutils literal\"><span class=\"pre\">BaseModel</span></code> include:</p>\n<ul class=\"simple\">\n<li><code class=\"docutils literal\"><span class=\"pre\">self.__init__()</span></code>. Define the model's parameters related to the architecture. You should call the super class's constructor at first.</li>\n<li><code class=\"docutils literal\"><span class=\"pre\">self.build()</span></code>. Build the architecture here. You should construct the graph at the beginning of this function and call the super class's <code class=\"docutils literal\"><span class=\"pre\">build()</span></code> function at the end.</li>\n<li><code class=\"docutils literal\"><span class=\"pre\">self._input</span></code>. The <code class=\"docutils literal\"><span class=\"pre\">dict</span></code> used to record the acceptable inputs of the model, whose keys are the parameter names in <code class=\"docutils literal\"><span class=\"pre\">model.fit()</span></code> and <code class=\"docutils literal\"><span class=\"pre\">model.predict()</span></code> and values are the name of related tensors.</li>\n<li><code class=\"docutils literal\"><span class=\"pre\">self._output</span></code>. The <code class=\"docutils literal\"><span class=\"pre\">dict</span></code> used to record the outputs of the model. You should fill the required keys <code class=\"docutils literal\"><span class=\"pre\">prediction</span></code> and <code class=\"docutils literal\"><span class=\"pre\">loss</span></code> with the names of tensors in your case.</li>\n<li><code class=\"docutils literal\"><span class=\"pre\">self._op</span></code>. The <code class=\"docutils literal\"><span class=\"pre\">dict</span></code> used to define all the operations for the model. Basic usage for it is to record the <strong>training operation</strong>, for example, the minimizing loss operation of an optimizer. Use key <code class=\"docutils literal\"><span class=\"pre\">train_op</span></code> to record it.</li>\n</ul>\n<p>For more examples, you can refer to the implementations of build-in models in <a class=\"reference external\" href=\"../UCTB.model.html#uctb-model-package\"><code class=\"docutils literal\"><span class=\"pre\">UCTB.model</span></code></a>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">UCTB.model_unit</span> <span class=\"kn\">import</span> <span class=\"n\">BaseModel</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">MyModel</span><span class=\"p\">(</span><span class=\"n\">BaseModel</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 \n                 <span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;my_model&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span>\n                <span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">MyModel</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"n\">code_version</span><span class=\"p\">,</span> \n                                      <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"n\">model_dir</span><span class=\"p\">,</span> <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"n\">gpu_device</span><span class=\"p\">)</span>\n        <span class=\"o\">...</span>\n        \n    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n            <span class=\"o\">...</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;inputs&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;targets&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">targets</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            \n            <span class=\"o\">...</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">predictions</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">loss</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">train_op</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            \n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">MyModel</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">(</span><span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"n\">init_vars</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span> \n</pre></div>\n</div>\n<p>Next, in a concrete case, we will realize a <strong>Long short-term memory (LSTM)</strong> model to make the all-station prediction that accepts time series of <code class=\"docutils literal\"><span class=\"pre\">717</span></code> stations and predict the future of them as a whole.</p>\n<p>For the mechanism of LSTM, you can refer to\n<a class=\"reference external\" href=\"https://www.researchgate.net/profile/Felix_Gers/publication/12292425_Learning_to_Forget_Continual_Prediction_with_LSTM/links/5759414608ae9a9c954e84c5/Learning-to-Forget-Continual-Prediction-with-LSTM.pdf\">Gers, F. A., Schmidhuber, J., &amp; Cummins, F. (1999). Learning to forget: Continual prediction with LSTM</a>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">tensorflow</span> <span class=\"k\">as</span> <span class=\"nn\">tf</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.model_unit</span> <span class=\"kn\">import</span> <span class=\"n\">BaseModel</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.preprocess</span> <span class=\"kn\">import</span> <span class=\"n\">SplitData</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.evaluation</span> <span class=\"kn\">import</span> <span class=\"n\">metric</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"k\">class</span> <span class=\"nc\">LSTM</span><span class=\"p\">(</span><span class=\"n\">BaseModel</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                 <span class=\"n\">num_stations</span><span class=\"p\">,</span> \n                 <span class=\"n\">num_layers</span><span class=\"p\">,</span> \n                 <span class=\"n\">num_units</span><span class=\"p\">,</span> \n                 <span class=\"n\">input_steps</span><span class=\"p\">,</span> \n                 <span class=\"n\">input_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">output_steps</span><span class=\"p\">,</span>\n                 <span class=\"n\">output_dim</span><span class=\"p\">,</span>\n                 <span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;my_lstm&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"s1\">&#39;0&#39;</span><span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">LSTM</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">code_version</span><span class=\"o\">=</span><span class=\"n\">code_version</span><span class=\"p\">,</span> \n                                   <span class=\"n\">model_dir</span><span class=\"o\">=</span><span class=\"n\">model_dir</span><span class=\"p\">,</span> <span class=\"n\">gpu_device</span><span class=\"o\">=</span><span class=\"n\">gpu_device</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span> <span class=\"o\">=</span> <span class=\"n\">num_stations</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_layers</span> <span class=\"o\">=</span> <span class=\"n\">num_layers</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_units</span> <span class=\"o\">=</span> <span class=\"n\">num_units</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_steps</span> <span class=\"o\">=</span> <span class=\"n\">input_steps</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_dim</span> <span class=\"o\">=</span> <span class=\"n\">input_dim</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_steps</span> <span class=\"o\">=</span> <span class=\"n\">output_steps</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_dim</span> <span class=\"o\">=</span> <span class=\"n\">output_dim</span>\n        \n    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_graph</span><span class=\"o\">.</span><span class=\"n\">as_default</span><span class=\"p\">():</span>\n            <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span><span class=\"p\">,</span> \n                                                       <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_steps</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_dim</span><span class=\"p\">))</span>\n            <span class=\"n\">targets</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">placeholder</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span><span class=\"p\">,</span>\n                                                       <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_steps</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_dim</span><span class=\"p\">))</span>\n            <span class=\"c1\"># record the inputs of the model</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;inputs&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_input</span><span class=\"p\">[</span><span class=\"s1\">&#39;targets&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">targets</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n            <span class=\"n\">inputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_steps</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_dim</span><span class=\"p\">))</span>\n            \n            <span class=\"k\">def</span> <span class=\"nf\">get_a_cell</span><span class=\"p\">(</span><span class=\"n\">num_units</span><span class=\"p\">):</span>\n                <span class=\"n\">lstm</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">rnn_cell</span><span class=\"o\">.</span><span class=\"n\">BasicLSTMCell</span><span class=\"p\">(</span><span class=\"n\">num_units</span><span class=\"p\">,</span> <span class=\"n\">state_is_tuple</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n                <span class=\"k\">return</span> <span class=\"n\">lstm</span>\n            \n            <span class=\"n\">stacked_cells</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">contrib</span><span class=\"o\">.</span><span class=\"n\">rnn</span><span class=\"o\">.</span><span class=\"n\">MultiRNNCell</span><span class=\"p\">([</span><span class=\"n\">get_a_cell</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_units</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_layers</span><span class=\"p\">)],</span> <span class=\"n\">state_is_tuple</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n            <span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">final_state</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">nn</span><span class=\"o\">.</span><span class=\"n\">dynamic_rnn</span><span class=\"p\">(</span><span class=\"n\">stacked_cells</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n            \n            <span class=\"n\">stacked_outputs</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_units</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">input_steps</span><span class=\"p\">))</span>\n            <span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">layers</span><span class=\"o\">.</span><span class=\"n\">dense</span><span class=\"p\">(</span><span class=\"n\">stacked_outputs</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_steps</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span><span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_dim</span><span class=\"p\">)</span>\n            <span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">predictions</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">num_stations</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_steps</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">output_dim</span><span class=\"p\">))</span>\n            \n            <span class=\"n\">loss</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">sqrt</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">reduce_mean</span><span class=\"p\">(</span><span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">square</span><span class=\"p\">(</span><span class=\"n\">predictions</span> <span class=\"o\">-</span> <span class=\"n\">targets</span><span class=\"p\">)))</span>\n            <span class=\"n\">train_op</span> <span class=\"o\">=</span> <span class=\"n\">tf</span><span class=\"o\">.</span><span class=\"n\">train</span><span class=\"o\">.</span><span class=\"n\">AdamOptimizer</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">minimize</span><span class=\"p\">(</span><span class=\"n\">loss</span><span class=\"p\">)</span>\n            \n            <span class=\"c1\"># record the outputs and the operation of the model</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">predictions</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_output</span><span class=\"p\">[</span><span class=\"s1\">&#39;loss&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">loss</span><span class=\"o\">.</span><span class=\"n\">name</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_op</span><span class=\"p\">[</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">train_op</span><span class=\"o\">.</span><span class=\"n\">name</span>\n        \n        <span class=\"c1\"># must call super class&#39; function to build </span>\n        <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">LSTM</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">(</span><span class=\"n\">init_vars</span><span class=\"o\">=</span><span class=\"n\">init_vars</span><span class=\"p\">,</span> <span class=\"n\">max_to_keep</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">)</span> \n</pre></div>\n</div>\n<p>Load the dataset by loader and transform them into the formats your model accepts. If the loader APIs are not filled your demands, you can inherit loader and wrapper it according to your desires (see <a class=\"reference external\" href=\"./quickstart.html\">Quickstart</a> for more details).</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">data_range</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">,</span> <span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s1\">&#39;Bike&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s1\">&#39;NYC&#39;</span><span class=\"p\">,</span>\n                                <span class=\"n\">closeness_len</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"n\">period_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">trend_len</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n                                <span class=\"n\">target_length</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">test_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.2</span><span class=\"p\">,</span> \n                                <span class=\"n\">normalize</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">with_lm</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">with_tpe</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n<span class=\"n\">train_y</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">expand_dims</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_y</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"n\">test_y</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">expand_dims</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_y</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">LSTM</span><span class=\"p\">(</span><span class=\"n\">num_stations</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">station_number</span><span class=\"p\">,</span> \n             <span class=\"n\">num_layers</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n             <span class=\"n\">num_units</span><span class=\"o\">=</span><span class=\"mi\">512</span><span class=\"p\">,</span> \n             <span class=\"n\">input_steps</span><span class=\"o\">=</span><span class=\"mi\">6</span><span class=\"p\">,</span> \n             <span class=\"n\">input_dim</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> \n             <span class=\"n\">output_steps</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> \n             <span class=\"n\">output_dim</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">()</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">trainable_vars</span><span class=\"p\">)</span>  <span class=\"c1\"># count the trainble parameters</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"mi\">6821581</span>\n</pre></div>\n</div>\n<p>Use your model to training and predicting. <code class=\"docutils literal\"><span class=\"pre\">model.fit()</span></code> method presets lots of useful functions, such as batch division and early stopping. Check them in <a class=\"reference external\" href=\"../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.fit\"><code class=\"docutils literal\"><span class=\"pre\">UCTB.model_unit.BaseModel.BaseModel.fit</span></code></a>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_closeness</span><span class=\"p\">,</span>\n          <span class=\"n\">targets</span><span class=\"o\">=</span><span class=\"n\">train_y</span><span class=\"p\">,</span>\n          <span class=\"n\">max_epoch</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span>\n          <span class=\"n\">batch_size</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span>\n          <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">train_sequence_len</span><span class=\"p\">,</span>\n          <span class=\"n\">validate_ratio</span><span class=\"o\">=</span><span class=\"mf\">0.1</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"n\">No</span> <span class=\"n\">model</span> <span class=\"n\">found</span><span class=\"p\">,</span> <span class=\"n\">start</span> <span class=\"n\">training</span>\n<span class=\"n\">Running</span> <span class=\"n\">Operation</span> <span class=\"p\">(</span><span class=\"s1\">&#39;train_op&#39;</span><span class=\"p\">,)</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.016053785</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.01606118</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.015499311</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015820855</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">2</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.015298592</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015657894</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">3</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.015163456</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015559187</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">4</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.015066812</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015342651</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">5</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.015016247</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015287879</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">6</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.014899823</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015249459</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">7</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.014773054</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015098239</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">8</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.014655286</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015097916</span>\n<span class=\"n\">Epoch</span> <span class=\"mi\">9</span><span class=\"p\">:</span> <span class=\"n\">train_loss</span> <span class=\"mf\">0.014558283</span> <span class=\"n\">val_loss</span> <span class=\"mf\">0.015108417</span>\n</pre></div>\n</div>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_closeness</span><span class=\"p\">,</span> \n                            <span class=\"n\">sequence_length</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">test_sequence_len</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Reverse the normalization by <code class=\"docutils literal\"><span class=\"pre\">data_loader</span></code> and evaluate the results:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">predictions</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">inverse_transform</span><span class=\"p\">(</span><span class=\"n\">predictions</span><span class=\"p\">[</span><span class=\"s1\">&#39;prediction&#39;</span><span class=\"p\">])</span>\n<span class=\"n\">targets</span> <span class=\"o\">=</span> <span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">normalizer</span><span class=\"o\">.</span><span class=\"n\">inverse_transform</span><span class=\"p\">(</span><span class=\"n\">test_y</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Test result&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">.</span><span class=\"n\">rmse</span><span class=\"p\">(</span><span class=\"n\">prediction</span><span class=\"o\">=</span><span class=\"n\">predictions</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"o\">=</span><span class=\"n\">targets</span><span class=\"p\">))</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"n\">Test</span> <span class=\"n\">result</span> <span class=\"mf\">2.9765626570592545</span>\n</pre></div>\n</div>\n<p>Since we only use a short period of the dataset (<code class=\"docutils literal\"><span class=\"pre\">data_range=0.1</span></code>) in this toy example, the result looks good compared with the <a class=\"reference external\" href=\"./all_results.html#results-on-bike\">experiment</a>. You can also take a try to test the completed dataset on your model.</p>\n</div>\n<div class=\"section\" id=\"build-your-own-graph-with-stmeta\">\n<h3>4.4.2. Build your own graph with STMeta<a class=\"headerlink\" href=\"#build-your-own-graph-with-stmeta\" title=\"Permalink to this headline\">¶</a></h3>\n<p>Next, we will use the Top-K graph as an example to illustrate how to build customized graphs in UCTB. All of the code in this section can be found <a class=\"reference external\" href=\"https://anonymous.4open.science/r/561305b5-e65e-46c6-9371-ae76b85109ee/Experiments/CustomizedDemo/\">here</a>.</p>\n<p><strong>Top-K graph</strong></p>\n<p>First of all, the customized graphs used in this section is called Top-K graph. We construct the corresponding adjacent graph by marking the point pair that consist of each point and its nearest K points as 1, and the others are marked as 0. Then, we use the adjacent graph to generate the laplacian matrix for input. The hyperparameter K is designed via ad-hoc heuristics. In this demonstration, we chose 23 as the value of K.</p>\n<p><strong>Realize TopK graph analysis module</strong></p>\n<p>To adopt customized graphs (<em><strong>e.g.,</strong></em> Top-K) in UCTB, you should first build your own analysis class by inheriting <code class=\"docutils literal\"><span class=\"pre\">UCTB.preprocess.GraphGenerator</span> <span class=\"pre\">class</span></code>.</p>\n<p>It is worth noting that the ultimate goal is to generate the member variables: <code class=\"docutils literal\"><span class=\"pre\">self.LM</span></code> and <code class=\"docutils literal\"><span class=\"pre\">self.AM</span></code>, which is the input matrix of the graph. In this phase, we need to make the corresponding analytical implementation according to the type of the custom graph passed in.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># &quot;UCTB/preprocess/topKGraph.py&quot;</span>\n<span class=\"kn\">import</span> <span class=\"nn\">heapq</span>\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">from</span> <span class=\"nn\">UCTB.preprocess.GraphGenerator</span> <span class=\"kn\">import</span> <span class=\"n\">GraphGenerator</span>\n\n<span class=\"c1\"># Define the class: topKGraph</span>\n<span class=\"k\">class</span> <span class=\"nc\">topKGraph</span><span class=\"p\">(</span><span class=\"n\">GraphGenerator</span><span class=\"p\">):</span>  <span class=\"c1\"># Init NodeTrafficLoader</span>\n\n   <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n\n       <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">topKGraph</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n       \n       <span class=\"k\">for</span> <span class=\"n\">graph_name</span> <span class=\"ow\">in</span> <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;graph&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"s1\">&#39;-&#39;</span><span class=\"p\">):</span>\n\n<span class=\"c1\"># As the basic graph is implemented in GraphGenerator, you only need to implement your own graph function instead of the existing one.</span>\n           <span class=\"k\">if</span> <span class=\"n\">graph_name</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;topk&#39;</span><span class=\"p\">:</span>\n               <span class=\"n\">lat_lng_list</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([[</span><span class=\"nb\">float</span><span class=\"p\">(</span><span class=\"n\">e1</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">e1</span> <span class=\"ow\">in</span> <span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">:</span><span class=\"mi\">4</span><span class=\"p\">]]</span>\n                                        <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_station_info</span><span class=\"p\">])</span>\n               <span class=\"c1\"># Handling</span>\n               <span class=\"n\">AM</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">neighbour_adjacent</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">traffic_data_index</span><span class=\"p\">],</span>\n                                       <span class=\"n\">threshold</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;threshold_neighbour&#39;</span><span class=\"p\">]))</span>\n               <span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">adjacent_to_laplacian</span><span class=\"p\">(</span><span class=\"n\">AM</span><span class=\"p\">)</span>\n\n               <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">AM</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>  <span class=\"c1\"># Make AM</span>\n                   <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">AM</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">AM</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n               <span class=\"k\">else</span><span class=\"p\">:</span>\n                   <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">AM</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">vstack</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">AM</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">AM</span><span class=\"p\">[</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">newaxis</span><span class=\"p\">,</span> <span class=\"p\">:])))</span>\n\n               <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>  <span class=\"c1\"># Make LM</span>\n                   <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">LM</span><span class=\"p\">],</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n               <span class=\"k\">else</span><span class=\"p\">:</span>\n                   <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">vstack</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">LM</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">LM</span><span class=\"p\">[</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">newaxis</span><span class=\"p\">,</span> <span class=\"p\">:])))</span>\n\n<span class=\"c1\"># Implement the details of building the Top-K graph.</span>\n   <span class=\"k\">def</span> <span class=\"nf\">neighbour_adjacent</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">lat_lng_list</span><span class=\"p\">,</span> <span class=\"n\">threshold</span><span class=\"p\">):</span>\n       <span class=\"n\">adjacent_matrix</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">),</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">)])</span>\n       <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">)):</span>\n           <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">lat_lng_list</span><span class=\"p\">)):</span>\n               <span class=\"n\">adjacent_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">haversine</span><span class=\"p\">(</span>\n                   <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">lat_lng_list</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n       <span class=\"n\">dis_matrix</span> <span class=\"o\">=</span> <span class=\"n\">adjacent_matrix</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n\n       <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">dis_matrix</span><span class=\"p\">)):</span>\n           <span class=\"n\">ind</span> <span class=\"o\">=</span> <span class=\"n\">heapq</span><span class=\"o\">.</span><span class=\"n\">nlargest</span><span class=\"p\">(</span><span class=\"n\">threshold</span><span class=\"p\">,</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">dis_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])),</span> <span class=\"n\">dis_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">take</span><span class=\"p\">)</span>\n           <span class=\"n\">dis_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"mi\">0</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">dis_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]))])</span>\n           <span class=\"n\">dis_matrix</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">ind</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">1</span>\n       <span class=\"n\">adjacent_matrix</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">adjacent_matrix</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">)</span>\n       <span class=\"k\">return</span> <span class=\"n\">adjacent_matrix</span>\n</pre></div>\n</div>\n<p><strong>Redefine the call statement of the above class</strong></p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># &quot;UCTB/Experiments/CustomizedDemo/STMeta_Obj_topk.py&quot;</span>\n\n<span class=\"c1\"># Import the Class: topKGraph</span>\n<span class=\"kn\">from</span> <span class=\"nn\">topKGraph</span> <span class=\"kn\">import</span> <span class=\"n\">topKGraph</span>\n<span class=\"c1\"># Call topKGraph to initialize and generate AM and LM</span>\n<span class=\"n\">graphBuilder</span> <span class=\"o\">=</span> <span class=\"n\">topKGraph</span><span class=\"p\">(</span><span class=\"n\">graph</span><span class=\"o\">=</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"s1\">&#39;graph&#39;</span><span class=\"p\">],</span>\n                         <span class=\"n\">data_loader</span><span class=\"o\">=</span><span class=\"n\">data_loader</span><span class=\"p\">,</span>\n                         <span class=\"n\">threshold_distance</span><span class=\"o\">=</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"s1\">&#39;threshold_distance&#39;</span><span class=\"p\">],</span>\n                         <span class=\"n\">threshold_correlation</span><span class=\"o\">=</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"s1\">&#39;threshold_correlation&#39;</span><span class=\"p\">],</span>\n                         <span class=\"n\">threshold_interaction</span><span class=\"o\">=</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"s1\">&#39;threshold_interaction&#39;</span><span class=\"p\">],</span>\n                         <span class=\"n\">threshold_neighbour</span><span class=\"o\">=</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"s1\">&#39;threshold_neighbour&#39;</span><span class=\"p\">])</span>\n<span class=\"c1\"># ......</span>\n</pre></div>\n</div>\n<p><strong>Modify the function call location</strong></p>\n<p>Add the new graph name when fitting model and then execute it for experiments. <a class=\"reference external\" href=\"https://github.com/uctb/UCTB/blob/master/Experiments/CustomizedDemo/Runner_topk.py\">code</a></p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">system</span><span class=\"p\">(</span><span class=\"s1\">&#39;python STMeta_Obj_topk.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml &#39;</span>\n          <span class=\"s1\">&#39;-p graph:Distance-Correlation-Line-TopK,MergeIndex:12&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>We conduct experiments on <code class=\"docutils literal\"><span class=\"pre\">Metro_Shanghai</span></code> dataset and use the <a class=\"reference external\" href=\"https://uctb.github.io/UCTB/md_file/all_results.html#stmeta-version\">STMeta_V1</a> to model both &quot;Distance-Correlation-Line&quot; graph and &quot;Distance-Correlation-Line-TopK&quot; and the results are following:</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\"><strong>Metro: Shanghai</strong></th>\n<th align=\"center\">Graph</th>\n<th align=\"center\">Test-RMSE</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">STMeta_V1</td>\n<td align=\"center\">Distance-Correlation-Line</td>\n<td align=\"center\">153.17</td>\n</tr>\n<tr>\n<td align=\"center\">STMeta_V1</td>\n<td align=\"center\">Distance-Correlation-Line-TopK</td>\n<td align=\"center\">140.82</td>\n</tr>\n</tbody>\n</table><p>The results show that the performance of STMeta_V1 with the graph &quot;Distance-Correlation-Line-TopK&quot; is better than &quot;Distance-Correlation-Line&quot; model and the RMSE is reduced by about 12.4%, which validates the effectiveness of the topk graph for spatiotemporal modeling STMeta algorithm.</p>\n<hr class=\"docutils\" />\n<p><u><a class=\"reference external\" href=\"../index.html\">Back To HomePage</a></u></p>\n</div>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"visualization_tool.html\" class=\"btn btn-neutral float-right\" title=\"5. Visualization-tool\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"urban_dataset.html\" class=\"btn btn-neutral\" title=\"3. Urban Datasets\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/src/image/README.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>&lt;no title&gt; &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../../../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../../../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../../../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../../../index.html\"/> \n\n  \n  <script src=\"../../../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../../../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../../../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../../../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../../../index.html\">Docs</a> &raquo;</li>\n        \n      <li>&lt;no title&gt;</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../../../_sources/md_file/src/image/README.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <p>Image resources</p>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../../../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../../../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/static/stable_test.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Stable Test Records &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../../index.html\"/> \n\n  \n  <script src=\"../../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../../index.html\">Docs</a> &raquo;</li>\n        \n      <li>Stable Test Records</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../../_sources/md_file/static/stable_test.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"stable-test-records\">\n<h1>Stable Test Records<a class=\"headerlink\" href=\"#stable-test-records\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"didi-chengdu\">\n<h2>DiDi Chengdu<a class=\"headerlink\" href=\"#didi-chengdu\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"parameters-for-building-graph\">\n<h3>Parameters for building graph<a class=\"headerlink\" href=\"#parameters-for-building-graph\" title=\"Permalink to this headline\">¶</a></h3>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">Notation</th>\n<th align=\"center\">explanation</th>\n<th align=\"center\">value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">TD</td>\n<td align=\"center\">threshold of distance graph</td>\n<td align=\"center\">7500m</td>\n</tr>\n<tr>\n<td align=\"center\">TI</td>\n<td align=\"center\">threshold of interaction graph</td>\n<td align=\"center\">30</td>\n</tr>\n<tr>\n<td align=\"center\">TC</td>\n<td align=\"center\">threshold of correlation graph</td>\n<td align=\"center\">0.65</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"parameters-for-building-model\">\n<h3>Parameters for building model<a class=\"headerlink\" href=\"#parameters-for-building-model\" title=\"Permalink to this headline\">¶</a></h3>\n<div class=\"highlight-json\"><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n    <span class=\"nt\">&quot;L&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;PT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;lr&quot;</span><span class=\"p\">:</span> <span class=\"mf\">5e-05</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">4</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DenseUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">32</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;LSTMUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;ESlength&quot;</span><span class=\"p\">:</span> <span class=\"mi\">500</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;patience&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Normalize&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;True&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TI&quot;</span><span class=\"p\">:</span> <span class=\"mf\">30.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">6</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;K&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALHeads&quot;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Graph&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Distance-Interaction-Correlation&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GLL&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span>\n<span class=\"p\">}</span>\n</pre></div>\n</div>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">实验编号</th>\n<th align=\"center\">模型版本含义</th>\n<th align=\"center\">Test-RMSE值</th>\n<th align=\"center\">Test-MAPE</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">6.98410</td>\n<td align=\"center\">0.35470</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.06971</td>\n<td align=\"center\">0.36585</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.00403</td>\n<td align=\"center\">0.34867</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.04557</td>\n<td align=\"center\">0.34797</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.05717</td>\n<td align=\"center\">0.36398</td>\n</tr>\n<tr>\n<td align=\"center\">6</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">6.97287</td>\n<td align=\"center\">0.34735</td>\n</tr>\n<tr>\n<td align=\"center\">7</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.03885</td>\n<td align=\"center\">0.35656</td>\n</tr>\n<tr>\n<td align=\"center\">8</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.09894</td>\n<td align=\"center\">0.36024</td>\n</tr>\n<tr>\n<td align=\"center\">9</td>\n<td align=\"center\">STMeta-V2</td>\n<td align=\"center\">7.02147</td>\n<td align=\"center\">0.33930</td>\n</tr>\n<tr>\n<td align=\"center\">均值、标准差</td>\n<td align=\"center\"></td>\n<td align=\"center\">均值 7.03252，标准差 0.03865</td>\n<td align=\"center\"></td>\n</tr>\n<tr>\n<td align=\"center\">平均耗时</td>\n<td align=\"center\"></td>\n<td align=\"center\">0.5h~1.5h</td>\n<td align=\"center\"></td>\n</tr>\n</tbody>\n</table></div>\n</div>\n<div class=\"section\" id=\"didi-xian\">\n<h2>DiDi Xian<a class=\"headerlink\" href=\"#didi-xian\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"highlight-json\"><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n    <span class=\"nt\">&quot;TrainDays&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DenseUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">32</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Graph&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Distance-Interaction-Correlation&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">6</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Train&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;False&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Dataset&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;DiDi&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GLL&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TD&quot;</span><span class=\"p\">:</span> <span class=\"mf\">7500.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALHeads&quot;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;patience&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Epoch&quot;</span><span class=\"p\">:</span> <span class=\"mi\">10000</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CodeVersion&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ST0&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">4</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TC&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.65</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Device&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;L&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;PT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;ESlength&quot;</span><span class=\"p\">:</span> <span class=\"mi\">500</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;LSTMUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TI&quot;</span><span class=\"p\">:</span> <span class=\"mf\">30.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Normalize&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;True&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;City&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Xian&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;lr&quot;</span><span class=\"p\">:</span> <span class=\"mf\">5e-05</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DataRange&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;BatchSize&quot;</span><span class=\"p\">:</span> <span class=\"mi\">128</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;K&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Group&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Xian&quot;</span>\n<span class=\"p\">}</span>\n</pre></div>\n</div>\n<p>STMeta-V2 多次实验结果，每次实验耗时 0.5h~1.5h</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">实验编号</th>\n<th align=\"center\">Test-RMSE</th>\n<th align=\"center\">Test-MAPE</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">5.80502</td>\n<td align=\"center\">0.36022</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">5.88970</td>\n<td align=\"center\">0.35590</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">6.00412</td>\n<td align=\"center\">0.45126</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">5.93798</td>\n<td align=\"center\">0.37956</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">6.01064</td>\n<td align=\"center\">0.39242</td>\n</tr>\n<tr>\n<td align=\"center\">6</td>\n<td align=\"center\">5.89309</td>\n<td align=\"center\">0.40803</td>\n</tr>\n<tr>\n<td align=\"center\">7</td>\n<td align=\"center\">5.84786</td>\n<td align=\"center\">0.35915</td>\n</tr>\n<tr>\n<td align=\"center\">8</td>\n<td align=\"center\">5.88188</td>\n<td align=\"center\">0.36777</td>\n</tr>\n<tr>\n<td align=\"center\">9</td>\n<td align=\"center\">5.97407</td>\n<td align=\"center\">0.42393</td>\n</tr>\n<tr>\n<td align=\"center\">10</td>\n<td align=\"center\">5.80497</td>\n<td align=\"center\">0.37014</td>\n</tr>\n</tbody>\n</table><p>最终结果：Test-RMSE 均值 5.90493，标准差 0.07142</p>\n<p>Metro Shanghai</p>\n<div class=\"highlight-json\"><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n    <span class=\"nt\">&quot;TrainDays&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;patience&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Train&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;False&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">4</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;City&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ShanghaiV1&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;ESlength&quot;</span><span class=\"p\">:</span> <span class=\"mi\">500</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;K&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GLL&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;LSTMUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Normalize&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;True&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;PT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Epoch&quot;</span><span class=\"p\">:</span> <span class=\"mi\">10000</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TI&quot;</span><span class=\"p\">:</span> <span class=\"mf\">100.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;lr&quot;</span><span class=\"p\">:</span> <span class=\"mf\">2e-05</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Dataset&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Metro&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DenseUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">32</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;L&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Group&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Shanghai&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Graph&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Distance-line-Correlation&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DataRange&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALHeads&quot;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CodeVersion&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ST_Sim_0&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">6</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TD&quot;</span><span class=\"p\">:</span> <span class=\"mf\">5000.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TC&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.7</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;BatchSize&quot;</span><span class=\"p\">:</span> <span class=\"mi\">128</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Device&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1&quot;</span>\n<span class=\"p\">}</span>\n</pre></div>\n</div>\n<p>STMeta-V2 多次实验结果，每次实验耗时 6.5h~7.5h</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">实验编号</th>\n<th align=\"center\">Test-RMSE</th>\n<th align=\"center\">Test-MAPE</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">148.88104</td>\n<td align=\"center\">0.13178</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">149.58350</td>\n<td align=\"center\">0.14325</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">168.16162</td>\n<td align=\"center\">0.14498</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">155.88750</td>\n<td align=\"center\">0.19575</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">155.09171</td>\n<td align=\"center\">0.18060</td>\n</tr>\n<tr>\n<td align=\"center\">6</td>\n<td align=\"center\">166.13303</td>\n<td align=\"center\">0.18040</td>\n</tr>\n<tr>\n<td align=\"center\">7</td>\n<td align=\"center\">157.08799</td>\n<td align=\"center\">0.15245</td>\n</tr>\n</tbody>\n</table><p>最终结果：Test-RMSE 均值 157.26091，标准差 6.90058</p>\n</div>\n<div class=\"section\" id=\"chargestation-beijing\">\n<h2>ChargeStation Beijing<a class=\"headerlink\" href=\"#chargestation-beijing\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"highlight-json\"><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n    <span class=\"nt\">&quot;GALUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TD&quot;</span><span class=\"p\">:</span> <span class=\"mf\">1000.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TI&quot;</span><span class=\"p\">:</span> <span class=\"mf\">500.0</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;K&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Train&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;False&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">6</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;patience&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;ESlength&quot;</span><span class=\"p\">:</span> <span class=\"mi\">200</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Graph&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Distance-Correlation&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Normalize&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;True&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;lr&quot;</span><span class=\"p\">:</span> <span class=\"mf\">2e-05</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Device&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;0&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;BatchSize&quot;</span><span class=\"p\">:</span> <span class=\"mi\">128</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;LSTMUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">64</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;City&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Beijing&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TrainDays&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;CodeVersion&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ST_Sim1_0&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">4</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GALHeads&quot;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DenseUnits&quot;</span><span class=\"p\">:</span> <span class=\"mi\">32</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;PT&quot;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Group&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Beijing&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;L&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;DataRange&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;All&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;TC&quot;</span><span class=\"p\">:</span> <span class=\"mf\">0.1</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Epoch&quot;</span><span class=\"p\">:</span> <span class=\"mi\">10000</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;Dataset&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ChargeStation&quot;</span><span class=\"p\">,</span>\n    <span class=\"nt\">&quot;GLL&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span>\n<span class=\"p\">}</span>\n</pre></div>\n</div>\n<p>STMeta-V2 多次实验结果 (暂时只跑了4次)，每次实验耗时约 10h</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">实验编号</th>\n<th align=\"center\">Test-RMSE</th>\n<th align=\"center\">Test-MAPE</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">0.80954</td>\n<td align=\"center\">0.22925</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">0.82956</td>\n<td align=\"center\">0.23242</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">0.82393</td>\n<td align=\"center\">0.22467</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">0.81360</td>\n<td align=\"center\">0.22932</td>\n</tr>\n</tbody>\n</table><p>最终结果：Test-RMSE 均值 0.81915，标准差 0.0079745</p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/static/transfer_record.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Check-In与POI数据处理方法 &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../../index.html\"/> \n\n  \n  <script src=\"../../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../../index.html\">Docs</a> &raquo;</li>\n        \n      <li>Check-In与POI数据处理方法</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../../_sources/md_file/static/transfer_record.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"check-inpoi\">\n<h1>Check-In与POI数据处理方法<a class=\"headerlink\" href=\"#check-inpoi\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"id1\">\n<h2>数据详情<a class=\"headerlink\" href=\"#id1\" title=\"Permalink to this headline\">¶</a></h2>\n<ol class=\"simple\">\n<li>时间范围：Apr 2012 ~ Sept 2013</li>\n<li>三个城市的POI数量与check-in数量</li>\n</ol>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">城市</th>\n<th align=\"center\">POI数量(计算城市中心为原点、半径为50km的POI数量)</th>\n<th align=\"center\">日均check-in数量(粗略计算所有站点附近1km的checkin数量总和)</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">NYC</td>\n<td align=\"center\">71310</td>\n<td align=\"center\">工作日11707，节假日11358</td>\n</tr>\n<tr>\n<td align=\"center\">Chicago</td>\n<td align=\"center\">21949</td>\n<td align=\"center\">工作日2549，节假日2692</td>\n</tr>\n<tr>\n<td align=\"center\">DC</td>\n<td align=\"center\">21087</td>\n<td align=\"center\">工作日6049，节假日5450</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"check-in\">\n<h2>Check-In 特征计算方法<a class=\"headerlink\" href=\"#check-in\" title=\"Permalink to this headline\">¶</a></h2>\n<p>计算 2013-07-15 到 2013-09-15 之间，各个自行车站点附近1km的checkin总数量，按照工作日和节假日分开，即每个站点的特征维度为48，分别为工作日、节假日的24小时checkin</p>\n</div>\n<div class=\"section\" id=\"poi\">\n<h2>POI特征计算方法<a class=\"headerlink\" href=\"#poi\" title=\"Permalink to this headline\">¶</a></h2>\n<p>一共有428种POI，每个站点统计附近1km出现的POI类型，即每个站点有428维特征</p>\n</div>\n<div class=\"section\" id=\"id2\">\n<h2>特征相似度方法<a class=\"headerlink\" href=\"#id2\" title=\"Permalink to this headline\">¶</a></h2>\n<p>Cosine Similarity</p>\n</div>\n</div>\n<div class=\"section\" id=\"id3\">\n<h1>使用Check-In数据进行相似站点的匹配<a class=\"headerlink\" href=\"#id3\" title=\"Permalink to this headline\">¶</a></h1>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">SD</th>\n<th align=\"center\">TD</th>\n<th align=\"center\">transfer-ratio</th>\n<th align=\"center\">TD-训练样本数量</th>\n<th align=\"center\">TD-Direct</th>\n<th align=\"center\">TD-FT</th>\n<th align=\"center\">TD-Transfer</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>5.15155</strong></td>\n<td align=\"center\">8.97297</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83186</strong></td>\n<td align=\"center\">5.60889</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.79484</strong></td>\n<td align=\"center\">4.86073</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83927</strong></td>\n<td align=\"center\">5.09481</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\"><strong>3.65903</strong></td>\n<td align=\"center\">3.67704</td>\n<td align=\"center\">35.02312</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.38682</strong></td>\n<td align=\"center\">4.10283</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.39081</strong></td>\n<td align=\"center\">3.44701</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.16186</strong></td>\n<td align=\"center\">3.36458</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>6.19588</strong></td>\n<td align=\"center\">8.28328</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.57436</strong></td>\n<td align=\"center\">5.89025</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.54711</strong></td>\n<td align=\"center\">5.64965</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.26407</strong></td>\n<td align=\"center\">6.34057</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.87629</strong></td>\n<td align=\"center\">5.78612</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\"><strong>4.32390</strong></td>\n<td align=\"center\">4.99620</td>\n<td align=\"center\">4.85723</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.26380</strong></td>\n<td align=\"center\">3.38408</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.15168</strong></td>\n<td align=\"center\">3.27858</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>4.43069</strong></td>\n<td align=\"center\">12.75022</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.94628</strong></td>\n<td align=\"center\">4.34232</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.93868</strong></td>\n<td align=\"center\">4.52421</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\">3.46738</td>\n<td align=\"center\"><strong>3.44230</strong></td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.58924</strong></td>\n<td align=\"center\">4.46261</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.29204</strong></td>\n<td align=\"center\">4.51947</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.22782</strong></td>\n<td align=\"center\">3.44588</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.09117</strong></td>\n<td align=\"center\">3.17292</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"id4\">\n<h1>使用POI信息进行相似站点匹配<a class=\"headerlink\" href=\"#id4\" title=\"Permalink to this headline\">¶</a></h1>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">SD</th>\n<th align=\"center\">TD</th>\n<th align=\"center\">transfer-ratio</th>\n<th align=\"center\">TD-训练样本数量</th>\n<th align=\"center\">TD-Direct</th>\n<th align=\"center\">TD-FT</th>\n<th align=\"center\">TD-Transfer</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>5.15155</strong></td>\n<td align=\"center\">7.74238</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83186</strong></td>\n<td align=\"center\">5.22502</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.79484</strong></td>\n<td align=\"center\">5.14237</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83927</strong></td>\n<td align=\"center\">5.11173</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\"><strong>3.65903</strong></td>\n<td align=\"center\">3.67704</td>\n<td align=\"center\">42.10733</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.38682</strong></td>\n<td align=\"center\">4.01524</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.39081</strong></td>\n<td align=\"center\">3.80654</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.16186</strong></td>\n<td align=\"center\">3.40228</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>6.19588</strong></td>\n<td align=\"center\">9.68558</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.57436</strong></td>\n<td align=\"center\">6.06141</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.54711</strong></td>\n<td align=\"center\">5.64207</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.26407</strong></td>\n<td align=\"center\">5.95202</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.87629</strong></td>\n<td align=\"center\">7.71124</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\"><strong>4.32390</strong></td>\n<td align=\"center\">4.99620</td>\n<td align=\"center\">5.20308</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.26380</strong></td>\n<td align=\"center\">3.41202</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.15168</strong></td>\n<td align=\"center\">3.36520</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>4.43069</strong></td>\n<td align=\"center\">8.70660</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.94628</strong></td>\n<td align=\"center\">4.68907</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.93868</strong></td>\n<td align=\"center\">4.71885</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.46738</strong></td>\n<td align=\"center\">3.54126</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.58924</strong></td>\n<td align=\"center\">4.54878</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.29204</strong></td>\n<td align=\"center\">6.51714</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.22782</strong></td>\n<td align=\"center\">3.50503</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.1</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.09117</strong></td>\n<td align=\"center\">3.35844</td>\n</tr>\n</tbody>\n</table><table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\">SD</th>\n<th align=\"center\">TD</th>\n<th align=\"center\">transfer-ratio</th>\n<th align=\"center\">TD-训练样本数量</th>\n<th align=\"center\">TD-Direct</th>\n<th align=\"center\">TD-FT</th>\n<th align=\"center\">TD-Transfer</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>5.15155</strong></td>\n<td align=\"center\">8.01029</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83186</strong></td>\n<td align=\"center\">5.52622</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.79484</strong></td>\n<td align=\"center\">5.30417</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.83927</strong></td>\n<td align=\"center\">6.07645</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">5.35244</td>\n<td align=\"center\"><strong>4.93593</strong></td>\n<td align=\"center\">5.96554</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\"><strong>3.65903</strong></td>\n<td align=\"center\">3.67704</td>\n<td align=\"center\">46.02469</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.38682</strong></td>\n<td align=\"center\">4.22828</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.39081</strong></td>\n<td align=\"center\">4.37432</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.16186</strong></td>\n<td align=\"center\">3.56052</td>\n</tr>\n<tr>\n<td align=\"center\">dc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">3.65903</td>\n<td align=\"center\"><strong>3.12768</strong></td>\n<td align=\"center\">3.39922</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>4.43069</strong></td>\n<td align=\"center\">11.41116</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.94628</strong></td>\n<td align=\"center\">4.55703</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.93868</strong></td>\n<td align=\"center\">4.31149</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.46738</strong></td>\n<td align=\"center\">3.59811</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">chicago</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">5.17356</td>\n<td align=\"center\"><strong>3.37643</strong></td>\n<td align=\"center\">3.48236</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.58924</strong></td>\n<td align=\"center\">5.95973</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.29204</strong></td>\n<td align=\"center\">5.09110</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.22782</strong></td>\n<td align=\"center\">4.01670</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.09117</strong></td>\n<td align=\"center\">3.34005</td>\n</tr>\n<tr>\n<td align=\"center\">nyc</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">4.11176</td>\n<td align=\"center\"><strong>3.02813</strong></td>\n<td align=\"center\">3.31671</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>6.19588</strong></td>\n<td align=\"center\">9.18276</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.57436</strong></td>\n<td align=\"center\">5.94807</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.54711</strong></td>\n<td align=\"center\">6.02357</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.26407</strong></td>\n<td align=\"center\">6.02906</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">nyc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">7.48254</td>\n<td align=\"center\"><strong>5.21905</strong></td>\n<td align=\"center\">5.96555</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">1天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.87629</strong></td>\n<td align=\"center\">5.75511</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">3天</td>\n<td align=\"center\"><strong>4.32390</strong></td>\n<td align=\"center\">4.99620</td>\n<td align=\"center\">7.56254</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">5天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.26380</strong></td>\n<td align=\"center\">4.44143</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">7天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.15168</strong></td>\n<td align=\"center\">3.65643</td>\n</tr>\n<tr>\n<td align=\"center\">chicago</td>\n<td align=\"center\">dc</td>\n<td align=\"center\">0.2</td>\n<td align=\"center\">9天</td>\n<td align=\"center\">4.32390</td>\n<td align=\"center\"><strong>3.13602</strong></td>\n<td align=\"center\">3.25901</td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"transfer\">\n<h1>分析Transfer效果在城市中的分布<a class=\"headerlink\" href=\"#transfer\" title=\"Permalink to this headline\">¶</a></h1>\n<p>绿色的点表示transfer效果好于finetune，红色代表差于finetune</p>\n<div class=\"section\" id=\"target-city-dc\">\n<h2>Target City DC<a class=\"headerlink\" href=\"#target-city-dc\" title=\"Permalink to this headline\">¶</a></h2>\n<p>左侧为 Chicago=&gt;DC，Overall result ：Finetune 3.13602，Transfer 3.25901</p>\n<p>右侧为 NYC=&gt;DC，Overall result ：Finetune 3.02813，Transfer 3.31671</p>\n<p><img alt=\"1567254312266\" src=\"md_file/static/..%5Csrc%5Cimage%5Ctransfer_dc.png\" /></p>\n</div>\n<div class=\"section\" id=\"target-city-nyc\">\n<h2>Target City NYC<a class=\"headerlink\" href=\"#target-city-nyc\" title=\"Permalink to this headline\">¶</a></h2>\n<p>左侧为 DC =&gt; NYC，Overall result ：Finetune 4.93593，Transfer 5.96554</p>\n<p>右侧为 Chicago =&gt;NYC，Overall result ：Finetune 5.21905，Transfer 5.96555</p>\n<p><img alt=\"1567253682671\" src=\"md_file/static/..%5Csrc%5Cimage%5Ctransfer_nyc.png\" /></p>\n</div>\n<div class=\"section\" id=\"target-city-chicago\">\n<h2>Target City Chicago<a class=\"headerlink\" href=\"#target-city-chicago\" title=\"Permalink to this headline\">¶</a></h2>\n<p>左侧为 NYC=&gt;Chicago，Overall result ：Finetune 3.37643，Transfer 3.48236</p>\n<p>右侧为 DC=&gt;Chicago，Overall result ：Finetune 3.12768，Transfer 3.39922</p>\n<p><img alt=\"1567255183794\" src=\"md_file/static/..%5Csrc%5Cimage%5Ctransfer_chicago.png\" /></p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/uctb_group.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>8. About us (UCTB Group) &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"prev\" title=\"7. Benchmark\" href=\"all_results.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">8. About us (UCTB Group)</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#pi\">8.1. PI</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#key-contributors\">8.2. Key Contributors</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#past-contributors\">8.3. Past Contributors</a></li>\n</ul>\n</li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>8. About us (UCTB Group)</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/uctb_group.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"about-us-uctb-group\">\n<h1>8. About us (UCTB Group)<a class=\"headerlink\" href=\"#about-us-uctb-group\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"section\" id=\"pi\">\n<h2>8.1. PI<a class=\"headerlink\" href=\"#pi\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Leye Wang</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Feb</span> <span class=\"pre\">2019,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Assistant professor &#64; Key Lab of High Confidence Software Technologies, Department of Computer Science &amp; Technology, Peking University.</p>\n<p>Email: <a class=\"reference external\" href=\"mailto:leyewang&#37;&#52;&#48;pku&#46;edu&#46;cn\">leyewang<span>&#64;</span>pku<span>&#46;</span>edu<span>&#46;</span>cn</a></p>\n<p><a class=\"reference external\" href=\"https://cs.pku.edu.cn/info/1174/2334.htm\">Leye Wang's HomePage</a></p>\n<hr class=\"docutils\" />\n<p><strong>Longbiao Chen</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">March</span> <span class=\"pre\">2022,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Associate professor &#64; Department of Computer Science, Xiamen University, China</p>\n<p>Email: <a class=\"reference external\" href=\"mailto:longbiaochen&#37;&#52;&#48;xmu&#46;edu&#46;cn\">longbiaochen<span>&#64;</span>xmu<span>&#46;</span>edu<span>&#46;</span>cn</a></p>\n<p><a class=\"reference external\" href=\"https://longbiao.crowdsensing.cn/\">Longbiao Chen's HomePage</a></p>\n</div>\n<div class=\"section\" id=\"key-contributors\">\n<h2>8.2. Key Contributors<a class=\"headerlink\" href=\"#key-contributors\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Di Chai</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Feb</span> <span class=\"pre\">2019,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Ph.D student in computer science and engineering at Hong Kong University of Science and Technology.</p>\n<p>Email: dchai&#64;cse.ust.hk</p>\n<hr class=\"docutils\" />\n<p><strong>Liyue Chen</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Nov</span> <span class=\"pre\">2019,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Ph.D student in Peking University.</p>\n<p>Email:  chenliyue2019&#64;gmail.com</p>\n<hr class=\"docutils\" />\n<p><strong>Jiangyi Fang</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">April</span> <span class=\"pre\">2022,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Undergraduate student majored in Automation in Huazhong University of Science and Technology.</p>\n<p>Email:  fangjiangyi2001&#64;gmail.com</p>\n<hr class=\"docutils\" />\n<p><strong>Yayao Hong</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Sep</span> <span class=\"pre\">2022,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Master student in Fujian Key Laboratory of Sensing and Computing for Smart Cities at Xiamen University.</p>\n<p>Email:  hyymmmint&#64;stu.xmu.edu.cn</p>\n<hr class=\"docutils\" />\n<p><strong>Tengfei Liu</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">March</span> <span class=\"pre\">2023,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Undergraduate student in computer science and technology at China University of Geosciences.</p>\n<p>Email:  tf66366&#64;cug.edu.cn</p>\n<hr class=\"docutils\" />\n<p><strong>Xiuhuai Xie</strong> (active)</p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">July</span> <span class=\"pre\">2023,</span> <span class=\"pre\">till</span> <span class=\"pre\">now.</span></code></p>\n<p>Postgraduate student majored in Computer Technology in Xiamen University.\nEmail: trafalgar2001&#64;163.com</p>\n</div>\n<div class=\"section\" id=\"past-contributors\">\n<h2>8.3. Past Contributors<a class=\"headerlink\" href=\"#past-contributors\" title=\"Permalink to this headline\">¶</a></h2>\n<p><strong>Hang Zhu</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">March</span> <span class=\"pre\">2022,</span> <span class=\"pre\">Jul</span> <span class=\"pre\">2023.</span></code></p>\n<p>Master student in Fujian Key Laboratory of Sensing and Computing for Smart Cities at Xiamen University.</p>\n<p>Email:  zhuhang&#64;stu.xmu.edu.cn</p>\n<hr class=\"docutils\" />\n<p><strong>Jin Xu</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Jul</span> <span class=\"pre\">2019</span> <span class=\"pre\">to</span> <span class=\"pre\">Aug</span> <span class=\"pre\">2019.</span></code></p>\n<p>Undergraduate student in Peking University majoring in Data Science and Big Data Technology.</p>\n<p>Email: jinxu&#64;pku.edu.cn</p>\n<hr class=\"docutils\" />\n<p><strong>Wenjie Yang</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Nov</span> <span class=\"pre\">2019</span> <span class=\"pre\">to</span> <span class=\"pre\">Aug</span> <span class=\"pre\">2020.</span></code></p>\n<p>Master student in computer science and engineering at Hong Kong University of Science and Technology.</p>\n<p>Email: wjyccs&#64;gmail.com</p>\n<hr class=\"docutils\" />\n<p><strong>Xueqiao Xu</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">Jan</span> <span class=\"pre\">2020</span> <span class=\"pre\">to</span> <span class=\"pre\">Jul</span> <span class=\"pre\">2020.</span></code></p>\n<p>He got his bachelor' degree in Peking University majoring in Data Science and Big Data Technology.</p>\n<p>Email:  snowbridge&#64;foxmail.com</p>\n<hr class=\"docutils\" />\n<p><strong>Zhenyu Cui</strong></p>\n<p><code class=\"docutils literal\"><span class=\"pre\">From</span> <span class=\"pre\">May</span> <span class=\"pre\">2020</span> <span class=\"pre\">to</span> <span class=\"pre\">Nov</span> <span class=\"pre\">2020.</span></code></p>\n<p>Graduate student in University of Chinese Academy of Sciences, majoring in Computer Vision and Deep Learning.</p>\n<p>Email:  cuizhenyu18&#64;mails.ucas.ac.cn</p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n      \n        <a href=\"all_results.html\" class=\"btn btn-neutral\" title=\"7. Benchmark\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/update_guide.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"generator\" content=\"Docutils 0.18.1: http://docutils.sourceforge.net/\" />\n\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>&lt;no title&gt; &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n    <link rel=\"stylesheet\" href=\"_static/pygments.css\" type=\"text/css\" />\n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>&lt;no title&gt;</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/update_guide.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <p>The first thing is to install the UCTB library, in fact, if you want to update successfully, you must first install the UCTB library successfully。</p>\n<p>The second thing to do is to install the Sphinx-related library functions locally. Here are some of the related versions。\npip install Sphinx==5.1.1\npip install sphinx-markdown-tables==0.0.17\npip install sphinx-rtd-theme==1.2.1\npip install sphinxcontrib-applehelp==1.0.2\npip install sphinxcontrib-devhelp==1.0.2\npip install sphinxcontrib-htmlhelp==2.0.0\npip install sphinxcontrib-jsmath==1.0.1\npip install sphinxcontrib-qthelp==1.0.3\npip install sphinxcontrib-serializinghtml==1.1.5\npip install rtcat-sphinx-theme==0.1.1\npip install recommonmark==0.7.1\npip install commonmark==0.9.1\npip install sphinx-markdown-tables==0.0.17</p>\n<p>Next, locate the.md file that corresponds to the section you want to update,\nIf you want to add text, just copy and paste it, if you want to add a big title, you can use the form of a # title, if you want to add a secondary title, you can use the form of a ## title, and so on.</p>\n<p>When update docstrings, run this code in cmd:\nsphinx-apidoc -o . ../../UCTB\nsphinx-build -b html . ..\nsphinx-build -b html . _build\nThen you can get the html file generated after the update.</p>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/documentation_options.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/_sphinx_javascript_frameworks_compat.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/urban_dataset.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>3. Urban Datasets &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"4. Predictive Tool\" href=\"predictive_tool.html\"/>\n        <link rel=\"prev\" title=\"2. Installation\" href=\"installation.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">3. Urban Datasets</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#datasets-overview\">3.1. Datasets Overview</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#bike-datasets\">3.2. Bike Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#bus-datasets\">3.3. Bus Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#speed-datasets\">3.4. Speed Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#pedestrian-datasets\">3.5. Pedestrian Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#taxi-datasets\">3.6. Taxi Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#metro-datasets\">3.7. Metro Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#flow-speed-datasets\">3.8. Flow Speed Datasets</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#load-uctb-dataset\">3.9. Load UCTB Dataset</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#dataset-format\">3.9.1. Dataset format</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#use-datasets-from-urban-datasets\">3.9.2. Use datasets from Urban Datasets</a></li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#how-to-get-the-datasets-at-other-granularities\">3.10. How to get the datasets at other granularities?</a></li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#build-your-own-datasets\">3.11. Build your own datasets</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>3. Urban Datasets</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/urban_dataset.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"urban-datasets\">\n<h1>3. Urban Datasets<a class=\"headerlink\" href=\"#urban-datasets\" title=\"Permalink to this headline\">¶</a></h1>\n<p>UCTB is designed for urban computing in various scenarios. Currently, It releases <a class=\"reference external\" href=\"https://github.com/uctb/Urban-Dataset\">a public dataset repository</a> including bike sharing, ride sharing, traffic speed, and pedestrian counting applications. <strong>If you are interested in this project, making a contribution to the dataset is strongly welcomed :)</strong></p>\n<div class=\"section\" id=\"datasets-overview\">\n<h2>3.1. Datasets Overview<a class=\"headerlink\" href=\"#datasets-overview\" title=\"Permalink to this headline\">¶</a></h2>\n<p>Currently, UCTB offers the following datasets in 7 scenarios, with detailed information provided in the table below. We are constantly working to release more datasets in the future.</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"center\"><strong>Application</strong></th>\n<th align=\"center\"><strong>City</strong></th>\n<th align=\"center\"><strong>Time Range</strong></th>\n<th align=\"center\"><strong>Temporal Granularity</strong></th>\n<th align=\"center\"><strong>Dataset Link</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip\">66.0M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">Chicago</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip\">30.2M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bike-sharing</td>\n<td align=\"center\">DC</td>\n<td align=\"center\">2013.07.01-2017.09.30</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip\">31.0M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Pedestrian Count</td>\n<td align=\"center\">Melbourne</td>\n<td align=\"center\">2021.01.01-2022.11.01</td>\n<td align=\"center\">60 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip\">1.18M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Vehicle Speed</td>\n<td align=\"center\">LA</td>\n<td align=\"center\">2012.03.01-2012.06.28</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip\">11.8M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Vehicle Speed</td>\n<td align=\"center\">BAY</td>\n<td align=\"center\">2017.01.01-2017.07.01</td>\n<td align=\"center\">5 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip\">27.9M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Taxi Demand</td>\n<td align=\"center\">Chicago</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 minutes</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip\">6.1M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Bus</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2022.02.01-2024.01.13</td>\n<td align=\"center\">60 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip\">4.89M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Metro</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2022.02.01-2023.12.21</td>\n<td align=\"center\">60 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip\">11.3M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Traffic Flow</td>\n<td align=\"center\">Luzern</td>\n<td align=\"center\">2015.01.01-2016.01.01</td>\n<td align=\"center\">3 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Flow/3_minutes/Flow_Luzern.zip\">21M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">Chicago (community)</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip\">6.06</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">Chicago (census tract)</td>\n<td align=\"center\">2013.01.01-2018.01.01</td>\n<td align=\"center\">15 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip\">10M</a></td>\n</tr>\n<tr>\n<td align=\"center\">Ride-sharing</td>\n<td align=\"center\">NYC</td>\n<td align=\"center\">2009.01.01-2023.06.01</td>\n<td align=\"center\">5 mins</td>\n<td align=\"center\"><a href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/5_minutes/Taxi_NYC.zip\">36.9M</a></td>\n</tr>\n</tbody>\n</table></div>\n<div class=\"section\" id=\"bike-datasets\">\n<h2>3.2. Bike Datasets<a class=\"headerlink\" href=\"#bike-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The bike-sharing datasets are collected from U.S. open data portals including New York City (NYC, https://www.citibikenyc.com/system-data), Chicago (CHI, https://www.divvybikes.com/system-data), and DC (https://www.capitalbikeshare.com/system-data). The dataset time span for all three cities is more than four years. The total number of historical flow records is around 49 million, 13 million, and 14 million in NYC, Chicago, and DC, respectively, and each record contains the start station, start time, stop station, stop time, etc.</p>\n<p>The following shows the map visualization of bike stations in NYC, Chicago, and DC.</p>\n<div style=\"display: flex;\">\n  <img src=\"https://camo.githubusercontent.com/eb6a2130ac83330fa6e79276f561c3966c79b7cc90b6cba5b79980127faaa316/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f4e59432e6a7067\" alt=\"图片1\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/9bb00c6ffb052701433ec46dfe52e96365014a2aa3eab825dc4f52e319ff3d1d/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f4368696361676f2e6a7067\" alt=\"图片2\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/a57455f9f9ccba9ed12ec57b3d5d805d75f4577278c824834ea429dc844cf976/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f44432e6a7067\" alt=\"图片3\" style=\"flex: 1; max-width: 300px; height: auto;\">\n</div>\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Bike/</div>\n<div class=\"section\" id=\"bus-datasets\">\n<h2>3.3. Bus Datasets<a class=\"headerlink\" href=\"#bus-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The bus datasets are collected from DATA.NY.GOV: MTA Bus Hourly Ridership. This dataset is provided by the Metropolitan Transportation Authority and is available for public download. It offers bus ridership estimates on an hourly basis by bus route. Data collection started from February 2022 and has been regularly updated. The Bus_NYC dataset includes data up to January 13, 2024. The latest version can be accessed on the website mentioned above. The station info data is downloaded from NYU | Faculty Digital Archive: New York City Bus Routes, Dec 2019. It does not encompass all bus routes. So we discarded the traffic data for bus routes where station information was not found, ultimately retaining 226 bus routes.\nFollowing shows the map-visualization of Bus_NYC datasets.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Bus.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Data catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Bus</p>\n</div>\n<div class=\"section\" id=\"speed-datasets\">\n<h2>3.4. Speed Datasets<a class=\"headerlink\" href=\"#speed-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The two traffic speed datasets are widely used in STTP research: METR-LA and PEMS-BAY from Los Angeles (LA) County and Bay Area, respectively. In METR-LA, 207 sensors record highway vehicles’ speeds for four months; In PEMS-BAY, there are 325 sensors for six months. Each sensor can be seen as a station.</p>\n<p>Following shows the map-visualization of METR-LA and PEMS-BAY.</p>\n<div style=\"display: flex;\">\n  <img src=\"https://camo.githubusercontent.com/7beb63775a5bcd043923b5b749896af2d10358bc30e2c974f07a882e5b70b20a/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f4d4554525f4c412e706e67\" alt=\"图片1\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/091bdeb27f8c007a2b19adfe23c48e072d90f157cd033932dbd773cb47c55dad/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f50454d535f4241592e706e67\" alt=\"图片2\" style=\"flex: 1; max-width: 300px; height: auto;\">\n</div>\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Speed/</div>\n<div class=\"section\" id=\"pedestrian-datasets\">\n<h2>3.5. Pedestrian Datasets<a class=\"headerlink\" href=\"#pedestrian-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The pedestrian datasets are collected from open data website of Melbourne. The full datasets' timespan is over 10 years and the datasets are still being updated at a fixed frequency (i.e., 60 minutes). Due to the fact that some sites were not set up in the early days and some sites lacked data, we only choose about a year in temporal dimension and 55 stations in spatial dimension. There is also accessible information about sensors on the same website. In the dataset of sensor information, we obtain the name, the sensor's ID, the sensor's status(whether it is active or not), the latitude and longtitude of each sensor.\nFollowing shows the map-visualization of Pedestrian datasets in Melbourne.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Pedestrain_Melbourne.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Data catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Pedestrian</p>\n</div>\n<div class=\"section\" id=\"taxi-datasets\">\n<h2>3.6. Taxi Datasets<a class=\"headerlink\" href=\"#taxi-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The Taxi datasets are collected from the city of Chicago's open data portal and the city of New York's open data portal, where you are able to freely download Chicago city's and NYC's datasets for your own analysis. The datasets record taxi trips from these dimensions listed below: pickup and dropoff time, pickup and dropoff location, fee etc. In our dataset, we only consider the pickup info of each record. You can conduct more comprehensive analysis with the help of our datasets and the website.</p>\n<p>Taxi Chicago Dataset\nFacts in dataset description</p>\n<p>There are two candidate spatial discretization information: census tract and community area.\nFor each record, it will aggregate census tract granularity into community area due to privacy preserve.\nWhich granularity to choose</p>\n<p>Thus, we need to choose a proper granularity. According to the needs of downstream tasks (Spatio-temporal traffic prediction), we summarize two principles of spatial granularity selection:</p>\n<p>Spatial granularity as small as possible (especially in high-demand area).\nDemamd aggregated due to privacy as few as possible.\nOn one hand, time distribution of taxi demand in downtown is dense, and the probability of being aggregated is small. on the other hand, the time distribution of taxi demand in the suburbs is sparse, and the probability of being aggregated is high.</p>\n<p>Final datasets we open</p>\n<p>We finally choose to process two datasets: one is Taxi_Chicago, where only spatial granularity community area is used; another is Taxi_fine_grained_Chicago, where community area is used in suburbs while census tract is used in downtown.</p>\n<p>We highly recommend that you conduct more analysis on Taxi_fine_grained_Chicago. By the way, we have adopted a special operation that taxi demand of specific census tract in 15-minute time window equal or less than 2 will be set 2. This operation won't affect much because all of aggregation situation is ultimately caused by insufficient demand.</p>\n<p>Following shows the map-visualization of Taxi_Chicago datasets.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Chicago_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Following shows the map-visualization of Taxi_fine_grained_Chicago datasets.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Chicago_fine_grained_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Taxi NYC Datasets\nWe collect Taxi NYC dataset from these two websites: https://opendata.cityofnewyork.us/ and https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page. We also obtain information of taxi zones in New York from this website. As a result of size of dataset, we put it on the link with extraction code gw6p.</p>\n<p>Following shows the map-visualization of Taxi_NYC datasets.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Data catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Taxi</p>\n</div>\n<div class=\"section\" id=\"metro-datasets\">\n<h2>3.7. Metro Datasets<a class=\"headerlink\" href=\"#metro-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The metro datasets are collected from DATA.NY.GOV: MTA Subway Hourly Ridership. The Metro_NYC dataset is provided by the Metropolitan Transportation Authority and is available for public download. It offers estimates of subway ridership on an hourly basis by subway station complex. Data collection started from February 2022 and has been regularly updated. The Metro_NYC dataset includes data up to December 21, 2023. The latest version can be accessed on the website mentioned above.</p>\n<p>Following shows the map-visualization of station complex in NYC.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Metro.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\"><p>Data catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Metro</p>\n</div>\n<div class=\"section\" id=\"flow-speed-datasets\">\n<h2>3.8. Flow Speed Datasets<a class=\"headerlink\" href=\"#flow-speed-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The traffic flow datasets are collected from UTD19 - Research Collection. UTD19 is a large-scale traffic data set from over 20000 stationary detectors on urban roads in 40 cities worldwide making it the largest multi-city traffic data set publically available. In our dataset, we only consider the data for the city of Luzern. The dataset enriched location information of sensors with further attributes describing the location of the sensor with respect to the road network.\nFollowing shows the map-visualization of station complex in Luzern.</p>\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Luzern_Flow.png\" alt=\"Image\" style=\"max-width: 400px; height: auto;\"><p>Data catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Flow</p>\n</div>\n<div class=\"section\" id=\"load-uctb-dataset\">\n<h2>3.9. Load UCTB Dataset<a class=\"headerlink\" href=\"#load-uctb-dataset\" title=\"Permalink to this headline\">¶</a></h2>\n<!-- TODO: 介绍pickle --><p>The <code class=\"docutils literal\"><span class=\"pre\">pickle</span></code> module is an external library that comes built-in with Python and provides functionality for converting Python objects into a byte stream (serialization) and restoring them back to their original state (deserialization). We use it to help data format instances to transform between memory and disk.</p>\n<div class=\"section\" id=\"dataset-format\">\n<h3>3.9.1. Dataset format<a class=\"headerlink\" href=\"#dataset-format\" title=\"Permalink to this headline\">¶</a></h3>\n<p>We've collected some public datasets and processing them into UCTB dataset format. UCTB dataset is a python build-in dictionary object that could be loaded by pickle package. Here is the example of UCTB dataset.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># Let&#39;s say ``my_dataset`` is your dataset.</span>\n<span class=\"n\">my_dataset</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;TimeRange&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s1\">&#39;YYYY-MM-DD&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;YYYY-MM-DD&#39;</span><span class=\"p\">],</span>\n    <span class=\"s2\">&quot;TimeFitness&quot;</span><span class=\"p\">:</span> <span class=\"mi\">60</span><span class=\"p\">,</span> <span class=\"c1\"># Minutes</span>\n    \n    <span class=\"s2\">&quot;Node&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;TrafficNode&quot;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">,</span> <span class=\"c1\"># With shape [time, num-of-node]</span>\n        <span class=\"s2\">&quot;TrafficMonthlyInteraction&quot;</span><span class=\"p\">:</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">,</span> <span class=\"c1\"># With shape [month, num-of-node. num-of-node]</span>\n        <span class=\"s2\">&quot;StationInfo&quot;</span><span class=\"p\">:</span> <span class=\"nb\">list</span> <span class=\"c1\"># elements in it should be [id, build-time, lat, lng, name]</span>\n        <span class=\"s2\">&quot;POI&quot;</span><span class=\"p\">:</span> <span class=\"p\">[]</span>\n    <span class=\"p\">},</span>\n\n    <span class=\"s2\">&quot;Grid&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;TrafficGrid&quot;</span><span class=\"p\">:</span> <span class=\"p\">[],</span>\n        <span class=\"s2\">&quot;GridLatLng&quot;</span><span class=\"p\">:</span> <span class=\"p\">[],</span>\n        <span class=\"s2\">&quot;POI&quot;</span><span class=\"p\">:</span> <span class=\"p\">[]</span>\n    <span class=\"p\">},</span>\n\n    <span class=\"s2\">&quot;ExternalFeature&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n         <span class=\"s2\">&quot;Weather&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"n\">time</span><span class=\"p\">,</span> <span class=\"n\">weather</span><span class=\"o\">-</span><span class=\"n\">feature</span><span class=\"o\">-</span><span class=\"n\">dim</span><span class=\"p\">]</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"use-datasets-from-urban-datasets\">\n<h3>3.9.2. Use datasets from Urban Datasets<a class=\"headerlink\" href=\"#use-datasets-from-urban-datasets\" title=\"Permalink to this headline\">¶</a></h3>\n<p>In this section, we will introduce how to get the dataset from Urban_Dataset and read the dataset using python.</p>\n<p>You are proposed to download the zip file from the <a class=\"reference external\" href=\"https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip\">link</a> and unzip the file. Let's say the following scripts are placed at the same directory with the dataset.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">pickle</span> <span class=\"k\">as</span> <span class=\"nn\">pkl</span>\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"n\">data_path</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Pedestrian_Melbourne.pkl&#39;</span>\n<span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"n\">data_path</span><span class=\"p\">,</span><span class=\"s1\">&#39;rb&#39;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">fp</span><span class=\"p\">:</span>\n    <span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">pkl</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"n\">fp</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Take a look at the necessary information about the dataset:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"c1\"># Traffic data </span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Data time range&#39;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;TimeRange&#39;</span><span class=\"p\">])</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Traffic data shape:&#39;</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficNode&#39;</span><span class=\"p\">]))</span>\n<span class=\"c1\"># The first dimension of data[&#39;Node&#39;][&#39;TrafficNode&#39;] is the length of time-sequence.</span>\n<span class=\"c1\"># The second dimension is the number of stations.</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Time fitness:&#39;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;TimeFitness&#39;</span><span class=\"p\">],</span> <span class=\"s1\">&#39;minutes&#39;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Time sequence length:&#39;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficNode&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Number of stations:&#39;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficNode&#39;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n</pre></div>\n</div>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span><span class=\"n\">Data</span> <span class=\"n\">time</span> <span class=\"nb\">range</span> <span class=\"p\">[</span><span class=\"s1\">&#39;2021-01-01&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;2022-11-01&#39;</span><span class=\"p\">]</span>\n<span class=\"n\">Traffic</span> <span class=\"n\">data</span> <span class=\"n\">shape</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"mi\">16056</span><span class=\"p\">,</span> <span class=\"mi\">55</span><span class=\"p\">)</span>\n<span class=\"n\">Time</span> <span class=\"n\">fitness</span><span class=\"p\">:</span> <span class=\"mi\">60</span> <span class=\"n\">minutes</span>\n<span class=\"n\">Time</span> <span class=\"n\">sequence</span> <span class=\"n\">length</span><span class=\"p\">:</span> <span class=\"mi\">16056</span>\n<span class=\"n\">Number</span> <span class=\"n\">of</span> <span class=\"n\">stations</span><span class=\"p\">:</span> <span class=\"mi\">55</span>\n</pre></div>\n</div>\n<p>Visualize the distribution of the traffic data:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">matplotlib.pyplot</span> <span class=\"k\">as</span> <span class=\"nn\">plt</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">plot</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">[</span><span class=\"s1\">&#39;Node&#39;</span><span class=\"p\">][</span><span class=\"s1\">&#39;TrafficNode&#39;</span><span class=\"p\">][:,</span> <span class=\"mi\">0</span><span class=\"p\">])</span>\n<span class=\"n\">plt</span><span class=\"o\">.</span><span class=\"n\">show</span><span class=\"p\">()</span>\n</pre></div>\n</div>\n<p><img alt=\"png\" src=\"../_images/toturial_p1_dataplot.png\" /></p>\n</div>\n</div>\n<div class=\"section\" id=\"how-to-get-the-datasets-at-other-granularities\">\n<h2>3.10. How to get the datasets at other granularities?<a class=\"headerlink\" href=\"#how-to-get-the-datasets-at-other-granularities\" title=\"Permalink to this headline\">¶</a></h2>\n<p>We could merge the fine-grained data to obtain the datasets at other granularities (e.g., by summing the 12 flows from the 5-minutes datasets to obtain 60-minutes datasets). UCTB provides the API to merge data. You could specify MergeIndex and MergeWay in the NodeTrafficLoader and GridTrafficLoader. Here is an example:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">UCTB.dataset</span> <span class=\"kn\">import</span> <span class=\"n\">NodeTrafficLoader</span>\n\n<span class=\"c1\"># loading 5-minutes datasets</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s2\">&quot;Bike&quot;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s2\">&quot;NYC&quot;</span><span class=\"p\">)</span> \n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_traffic</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span> <span class=\"c1\"># with shape (446976, 820)</span>\n\n<span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"s2\">&quot;Bike&quot;</span><span class=\"p\">,</span> <span class=\"n\">city</span><span class=\"o\">=</span><span class=\"s2\">&quot;NYC&quot;</span><span class=\"p\">,</span> <span class=\"n\">MergeIndex</span><span class=\"o\">=</span><span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"n\">MergeWay</span><span class=\"o\">=</span><span class=\"s2\">&quot;sum&quot;</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">data_loader</span><span class=\"o\">.</span><span class=\"n\">dataset</span><span class=\"o\">.</span><span class=\"n\">node_traffic</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">)</span> <span class=\"c1\"># with shape (37248, 820)</span>\n</pre></div>\n</div>\n</div>\n<div class=\"section\" id=\"build-your-own-datasets\">\n<h2>3.11. Build your own datasets<a class=\"headerlink\" href=\"#build-your-own-datasets\" title=\"Permalink to this headline\">¶</a></h2>\n<p>If you want to apply uctb dataloaders to your dataset, make your dataset compatible with the template as section 3.2.1 shown. And then save it with package <code class=\"docutils literal\"><span class=\"pre\">pickle</span></code> to a local path <code class=\"docutils literal\"><span class=\"pre\">pkl_file_name</span></code>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">pickle</span>\n<span class=\"n\">pkl_file_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;./my_dataset.pkl&#39;</span>  \n<span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"n\">pkl_file_name</span><span class=\"p\">,</span> <span class=\"s1\">&#39;wb&#39;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">handle</span><span class=\"p\">:</span>\n    <span class=\"n\">pickle</span><span class=\"o\">.</span><span class=\"n\">dump</span><span class=\"p\">(</span><span class=\"n\">my_dataset</span><span class=\"p\">,</span> <span class=\"n\">handle</span><span class=\"p\">,</span> <span class=\"n\">protocol</span><span class=\"o\">=</span><span class=\"n\">pickle</span><span class=\"o\">.</span><span class=\"n\">HIGHEST_PROTOCOL</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Finally, you can make uses of your dataset by UCTB's loader APIs:</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">data_loader</span> <span class=\"o\">=</span> <span class=\"n\">NodeTrafficLoader</span><span class=\"p\">(</span><span class=\"n\">dataset</span><span class=\"o\">=</span><span class=\"n\">pkl_file_name</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Also, we provide interface to help build your own dataset, through which we clarify whether a field is necessary or optional when building a UCTB dataset.</p>\n<p>To build a UCTB dataset, it is necessary to provide variables listed as below.</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\">Variable_name</th>\n<th align=\"left\">Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">time_fitness</td>\n<td align=\"left\">The length of the interval between adjacent slots</td>\n</tr>\n<tr>\n<td align=\"left\">time_range</td>\n<td align=\"left\">The time interval at the beginning and end of the data</td>\n</tr>\n<tr>\n<td align=\"left\">traffic_node</td>\n<td align=\"left\">The spatio-temporal information</td>\n</tr>\n<tr>\n<td align=\"left\">node_satation_info</td>\n<td align=\"left\">The basic information of each data collecting node</td>\n</tr>\n<tr>\n<td align=\"left\">dataset_name</td>\n<td align=\"left\">Name of the dataset</td>\n</tr>\n<tr>\n<td align=\"left\">city</td>\n<td align=\"left\">A variable used to integrate holiday and weather information to traffic data</td>\n</tr>\n</tbody>\n</table><p>Then, use the specified path to save the dataset, otherwise it will be saved in the current run-time path.</p>\n<p>Although it's diffcult to form an integrated function to include all situation you may meet during the transforming process, there are some procedures you might obey to simplify the data preprocessing.</p>\n<ul class=\"simple\">\n<li>Data preprocessing<ol>\n<li>Zero values</li>\n<li>Missing values(NA)</li>\n<li>Unknown values</li>\n<li>Abnormal values</li>\n<li>duplicates</li>\n<li>Statistics(station number and time slots)</li>\n</ol>\n</li>\n<li>Dictionary building<ul>\n<li>Basic information(time range and time fitness)</li>\n<li>Traffic node building<ul>\n<li>Spatio-temporal raster data building<ol>\n<li>Initialization</li>\n<li>iterate raw data table and fill the matrix</li>\n</ol>\n</li>\n<li>Station information</li>\n</ul>\n</li>\n<li>Traffic grid building</li>\n<li>External feature</li>\n</ul>\n</li>\n</ul>\n<p>Now, we assume that you have already finished variable preparation. UCTB provide API to assist you with dataset building.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">build_uctb_dataset</span><span class=\"p\">(</span><span class=\"n\">traffic_node</span><span class=\"o\">=</span><span class=\"n\">traffic_node</span><span class=\"p\">,</span> <span class=\"n\">time_fitness</span><span class=\"o\">=</span><span class=\"n\">time_fitness</span><span class=\"p\">,</span> \n                <span class=\"n\">node_station_info</span><span class=\"o\">=</span><span class=\"n\">node_station_info</span><span class=\"p\">,</span> <span class=\"n\">time_range</span><span class=\"o\">=</span><span class=\"n\">time_range</span><span class=\"p\">,</span> \n                <span class=\"n\">output_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;tmp_dir&#39;</span><span class=\"p\">,</span> <span class=\"n\">dataset_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;dataset&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Chicago&#39;</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Also, if you want to check what fields are in your datasets, set the argument <code class=\"docutils literal\"><span class=\"pre\">print_dataset</span></code> to <code class=\"docutils literal\"><span class=\"pre\">True</span></code>.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">build_uctb_dataset</span><span class=\"p\">(</span><span class=\"n\">traffic_node</span><span class=\"o\">=</span><span class=\"n\">traffic_node</span><span class=\"p\">,</span> <span class=\"n\">time_fitness</span><span class=\"o\">=</span><span class=\"n\">time_fitness</span><span class=\"p\">,</span> \n                <span class=\"n\">node_station_info</span><span class=\"o\">=</span><span class=\"n\">node_station_info</span><span class=\"p\">,</span> <span class=\"n\">time_range</span><span class=\"o\">=</span><span class=\"n\">time_range</span><span class=\"p\">,</span> \n                <span class=\"n\">output_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;tmp_dir&#39;</span><span class=\"p\">,</span> <span class=\"n\">dataset_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;dataset&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Chicago&#39;</span><span class=\"p\">,</span> <span class=\"n\">print_dataset</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</pre></div>\n</div>\n<p>Output:</p>\n<div class=\"highlight-default\"><div class=\"highlight\"><pre><span></span>dataset[TimeRange]:&lt;class &#39;list&#39;&gt;  (len=2)\ndataset[TimeFitness]:&lt;class &#39;int&#39;&gt;\ndataset[Node]:&lt;class &#39;dict&#39;&gt;{\n    dataset[Node][TrafficNode]:&lt;class &#39;numpy.ndarray&#39;&gt;  (shape=(37248, 532))\n    dataset[Node][StationInfo]:&lt;class &#39;list&#39;&gt;  (len=(532, 5))\n    dataset[Node][TrafficMonthlyInteraction]:&lt;class &#39;NoneType&#39;&gt;\n}\ndataset[Grid]:&lt;class &#39;dict&#39;&gt;{\n    dataset[Grid][TrafficGrid]:&lt;class &#39;NoneType&#39;&gt;\n    dataset[Grid][GridLatLng]:&lt;class &#39;NoneType&#39;&gt;\n}\ndataset[ExternalFeature]:&lt;class &#39;dict&#39;&gt;{\n    dataset[ExternalFeature][Weather]:&lt;class &#39;list&#39;&gt;  (len=0)\n}\ndataset[LenTimeSlots]:&lt;class &#39;int&#39;&gt;\n</pre></div>\n</div>\n<p>What's more, if you want to integrate additional information of the dataset, just specify the optional argument as bellow.</p>\n<table border=\"1\" class=\"docutils\">\n<thead>\n<tr>\n<th align=\"left\">Variable_name</th>\n<th align=\"left\">Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">traffic_monthly_interaction</td>\n<td align=\"left\">The interactive information among data collecting nodes.</td>\n</tr>\n<tr>\n<td align=\"left\">node_poi</td>\n<td align=\"left\">Point of interests conformed with node format</td>\n</tr>\n<tr>\n<td align=\"left\">grid_poi</td>\n<td align=\"left\">Point of interests conformed with grid format</td>\n</tr>\n<tr>\n<td align=\"left\">traffic_grid</td>\n<td align=\"left\">The spatio-temporal information in grid format.</td>\n</tr>\n<tr>\n<td align=\"left\">gird_lat_lng</td>\n<td align=\"left\">The basic information of each data collecting grid.</td>\n</tr>\n<tr>\n<td align=\"left\">external_feature_weather</td>\n<td align=\"left\">The weather information of each day.</td>\n</tr>\n</tbody>\n</table><p>for example, specify the argument <code class=\"docutils literal\"><span class=\"pre\">external_feature_weather</span></code> with numpy.array object.</p>\n<div class=\"highlight-python\"><div class=\"highlight\"><pre><span></span><span class=\"n\">build_uctb_dataset</span><span class=\"p\">(</span><span class=\"n\">traffic_node</span><span class=\"o\">=</span><span class=\"n\">traffic_node</span><span class=\"p\">,</span> <span class=\"n\">time_fitness</span><span class=\"o\">=</span><span class=\"n\">time_fitness</span><span class=\"p\">,</span> \n                <span class=\"n\">node_station_info</span><span class=\"o\">=</span><span class=\"n\">node_station_info</span><span class=\"p\">,</span> <span class=\"n\">time_range</span><span class=\"o\">=</span><span class=\"n\">time_range</span><span class=\"p\">,</span> \n                <span class=\"n\">output_dir</span><span class=\"o\">=</span><span class=\"s1\">&#39;tmp_dir&#39;</span><span class=\"p\">,</span> <span class=\"n\">dataset_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;dataset&#39;</span><span class=\"p\">,</span> <span class=\"n\">city</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;Chicago&#39;</span><span class=\"p\">,</span> \n                <span class=\"n\">print_dataset</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">external_feature_weather</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">([</span><span class=\"mi\">37248</span><span class=\"p\">,</span><span class=\"mi\">26</span><span class=\"p\">]))</span>\n</pre></div>\n</div>\n<p>The code above use zero matrix to specify the argument <code class=\"docutils literal\"><span class=\"pre\">external_feature_weather</span></code>. While in practical application scenario, you should substitute it with real feather matrix. The first dimension of the matrx is the number of time slots, and the second dimension corresponds to the dimension of weather features.</p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"predictive_tool.html\" class=\"btn btn-neutral float-right\" title=\"4. Predictive Tool\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"installation.html\" class=\"btn btn-neutral\" title=\"2. Installation\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/md_file/visualization_tool.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>5. Visualization-tool &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"../genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"../search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"../index.html\"/>\n        <link rel=\"next\" title=\"6. API Reference\" href=\"../APIReference.html\"/>\n        <link rel=\"prev\" title=\"4. Predictive Tool\" href=\"predictive_tool.html\"/> \n\n  \n  <script src=\"../_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul class=\"current\">\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1 current\"><a class=\"current reference internal\" href=\"#\">5. Visualization-tool</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#quick-start\">5.1. Quick Start</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#start-with-predefined-dataset\">5.1.1. Start with predefined dataset</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#start-with-prediction-and-ground-truth\">5.1.2. Start with prediction and ground truth</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#start-with-prediction-ground-truth-and-spatial-information\">5.1.3. Start with prediction, ground truth and spatial information</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#start-with-prediction-ground-truth-and-temporal-information\">5.1.4. Start with prediction, ground truth and temporal information</a></li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"#start-with-prediction-ground-truth-as-well-as-spatial-and-temporal-information\">5.1.5. Start with prediction, ground truth as well as spatial and temporal information</a></li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"#contribute-to-our-project\">5.2. Contribute to our project.</a></li>\n</ul>\n</li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\">Docs</a> &raquo;</li>\n        \n      <li>5. Visualization-tool</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"../_sources/md_file/visualization_tool.md.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"visualization-tool\">\n<h1>5. Visualization-tool<a class=\"headerlink\" href=\"#visualization-tool\" title=\"Permalink to this headline\">¶</a></h1>\n<p>We have developed a tool that integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis. Welcome to visit the <a class=\"reference external\" href=\"http://39.107.116.221/\">website</a> for a trial.</p>\n<div class=\"section\" id=\"quick-start\">\n<h2>5.1. Quick Start<a class=\"headerlink\" href=\"#quick-start\" title=\"Permalink to this headline\">¶</a></h2>\n<div class=\"section\" id=\"start-with-predefined-dataset\">\n<h3>5.1.1. Start with predefined dataset<a class=\"headerlink\" href=\"#start-with-predefined-dataset\" title=\"Permalink to this headline\">¶</a></h3>\n<p>You can click on the dropdown menu in the <code class=\"docutils literal\"><span class=\"pre\">predefined</span></code> module of the <code class=\"docutils literal\"><span class=\"pre\">Data</span> <span class=\"pre\">Loader</span></code>, select the dataset you need, and click <code class=\"docutils literal\"><span class=\"pre\">confirm</span></code> to obtain the required diagnosis and visualization.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_1.png\" alt=\"img\" style=\"zoom: 33%;\" /></div>\n<div class=\"section\" id=\"start-with-prediction-and-ground-truth\">\n<h3>5.1.2. Start with prediction and ground truth<a class=\"headerlink\" href=\"#start-with-prediction-and-ground-truth\" title=\"Permalink to this headline\">¶</a></h3>\n<p>You can upload specifically formatted TSV files for prediction and ground truth in the <code class=\"docutils literal\"><span class=\"pre\">upload</span></code> module of the Data Loader. Clicking <code class=\"docutils literal\"><span class=\"pre\">confirm</span></code> will enable you to obtain the corresponding diagnosis and visualization.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_2.png\" alt=\"img\" style=\"zoom: 33%;\" /></div>\n<div class=\"section\" id=\"start-with-prediction-ground-truth-and-spatial-information\">\n<h3>5.1.3. Start with prediction, ground truth and spatial information<a class=\"headerlink\" href=\"#start-with-prediction-ground-truth-and-spatial-information\" title=\"Permalink to this headline\">¶</a></h3>\n<p>You can upload specifically formatted TSV files for prediction, ground truth, and spatial information in the <code class=\"docutils literal\"><span class=\"pre\">upload</span></code> module of the <code class=\"docutils literal\"><span class=\"pre\">Data</span> <span class=\"pre\">Loader</span></code>. Clicking <code class=\"docutils literal\"><span class=\"pre\">confirm</span></code> will enable you to obtain the corresponding diagnosis and visualization.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_3.png\" alt=\"img\" style=\"zoom: 33%;\" /></div>\n<div class=\"section\" id=\"start-with-prediction-ground-truth-and-temporal-information\">\n<h3>5.1.4. Start with prediction, ground truth and temporal information<a class=\"headerlink\" href=\"#start-with-prediction-ground-truth-and-temporal-information\" title=\"Permalink to this headline\">¶</a></h3>\n<p>You can upload specifically formatted TSV files for prediction, and ground truth in the <code class=\"docutils literal\"><span class=\"pre\">upload</span></code> module of the 'Data Loader', along with the corresponding temporal information. Clicking <code class=\"docutils literal\"><span class=\"pre\">confirm</span></code> will enable you to obtain the corresponding diagnosis and visualization.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_4.png\" alt=\"img\" style=\"zoom: 33%;\" /></div>\n<div class=\"section\" id=\"start-with-prediction-ground-truth-as-well-as-spatial-and-temporal-information\">\n<h3>5.1.5. Start with prediction, ground truth as well as spatial and temporal information<a class=\"headerlink\" href=\"#start-with-prediction-ground-truth-as-well-as-spatial-and-temporal-information\" title=\"Permalink to this headline\">¶</a></h3>\n<p>You can upload specifically formatted TSV files for prediction, ground truth, and spatial information in the <code class=\"docutils literal\"><span class=\"pre\">upload</span></code> module of the <code class=\"docutils literal\"><span class=\"pre\">Data</span> <span class=\"pre\">Loader</span></code>, along with the corresponding temporal information. Clicking <code class=\"docutils literal\"><span class=\"pre\">confirm</span></code> will enable you to obtain the corresponding diagnosis and visualization.</p>\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_5.png\" alt=\".img\" style=\"zoom: 33%;\" /></div>\n</div>\n<div class=\"section\" id=\"contribute-to-our-project\">\n<h2>5.2. Contribute to our project.<a class=\"headerlink\" href=\"#contribute-to-our-project\" title=\"Permalink to this headline\">¶</a></h2>\n<p>The visualization-tool offers two usage options, which are accessing through the <a class=\"reference external\" href=\"http://39.107.116.221/\">website</a>, or using the source code(for contribution).</p>\n<p><strong>Step 1: Requirements</strong></p>\n<div class=\"highlight-vue\"><div class=\"highlight\"><pre><span></span>node == 16.14.0\nnpm == 8.3.1\n</pre></div>\n</div>\n<p><strong>Step 2: Clone repository and install dependencies</strong></p>\n<div class=\"highlight-Vue\"><div class=\"highlight\"><pre><span></span>git clone https://github.com/uctb/visualization-tool-UCTB.git \ncd visualization-tool-UCTB \nnpm install\n</pre></div>\n</div>\n<p><strong>Step 3: Start</strong></p>\n<div class=\"highlight-Vue\"><div class=\"highlight\"><pre><span></span>npm run serve\n</pre></div>\n</div>\n<p>Then you will see the following prompt on the screen:</p>\n<div class=\"highlight-vue\"><div class=\"highlight\"><pre><span></span> App running at:\n  - Local:   http://localhost:xxxx/ \n  - Network: http://ip:xxxx/\n</pre></div>\n</div>\n<p>You can customize the visualization tool in the source code to achieve visual effects that better fit the objectives. To better assist you in achieving personalization of the visualization tool, we recommend following these steps to implement it.</p>\n<p><strong>Step 1: Create your own component</strong></p>\n<div class=\"highlight-vue\"><div class=\"highlight\"><pre><span></span>&lt;template&gt;\n&lt;div&gt;Your own HTML&lt;/div&gt;\n&lt;/template&gt;\n\n&lt;script&gt;\nexport default {\n\tname: &#39;your own component name&#39;,\n    data(){}\n}\n&lt;/script&gt;\n\n&lt;style scoped&gt;\n /*Your own CSS*/\n&lt;/style&gt;\n</pre></div>\n</div>\n<p><strong>Step 2: Importing component in App.vue</strong></p>\n<div class=\"highlight-vue\"><div class=\"highlight\"><pre><span></span>&lt;script&gt;\nimport YourOwnComponent from &quot;./components/YourOwnComponent.vue&quot;\nexport default {\n\tname: &#39;App&#39;,\n    components: {\n     YourOwnComponent\n    }\n}\n&lt;/script&gt;\n</pre></div>\n</div>\n<p>More instructions on the usage of Vue can be referred to on the <a class=\"reference external\" href=\"https://v2.vuejs.org/\">website</a>. <strong>If you have any interesting or novel ideas, we highly welcome your pull request:)</strong></p>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n    <div class=\"rst-footer-buttons\" role=\"navigation\" aria-label=\"footer navigation\">\n      \n        <a href=\"../APIReference.html\" class=\"btn btn-neutral float-right\" title=\"6. API Reference\" accesskey=\"n\">Next →</a>\n      \n      \n        <a href=\"predictive_tool.html\" class=\"btn btn-neutral\" title=\"4. Predictive Tool\" accesskey=\"p\">← Previous</a>\n      \n    </div>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'../',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"../_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"../_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/modules.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>UCTB &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>UCTB</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/modules.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"uctb\">\n<h1>UCTB<a class=\"headerlink\" href=\"#uctb\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"UCTB.html\">UCTB package</a><ul>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.html#subpackages\">Subpackages</a><ul>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.dataset.html\">6.1. UCTB.dataset package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.data_loader\">6.1.1. UCTB.dataset.data_loader module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.dataset.html#module-UCTB.dataset.dataset\">6.1.2. UCTB.dataset.dataset module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.evaluation.html\">6.5. UCTB.evaluation package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.evaluation.html#module-UCTB.evaluation.metric\">6.5.1. UCTB.evaluation.metric module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.model.html\">6.4. UCTB.model package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ARIMA\">6.4.1. UCTB.model.ARIMA module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DCRNN\">6.4.2. UCTB.model.DCRNN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.DeepST\">6.4.3. UCTB.model.DeepST module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GeoMAN\">6.4.4. UCTB.model.GeoMAN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.HM\">6.4.5. UCTB.model.HM module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STMeta\">6.4.6. UCTB.model.STMeta module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_MGCN\">6.4.7. UCTB.model.ST_MGCN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ST_ResNet\">6.4.8. UCTB.model.ST_ResNet module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.XGBoost\">6.4.9. UCTB.model.XGBoost module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.AGCRN\">6.4.10. UCTB.model.AGCRN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.ASTGCN\">6.4.11. UCTB.model.ASTGCN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.GMAN\">6.4.12. UCTB.model.GMAN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#uctb-model-graphwavenet-module\">6.4.13. UCTB.model.GraphWaveNet module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STGCN\">6.4.14. UCTB.model.STGCN module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model.html#module-UCTB.model.STSGCN\">6.4.15. UCTB.model.STSGCN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.model_unit.html\">6.3. UCTB.model_unit package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.BaseModel\">6.3.1. UCTB.model_unit.BaseModel module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.DCRNN_CELL\">6.3.2. UCTB.model_unit.DCRNN_CELL module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.GraphModelLayers\">6.3.3. UCTB.model_unit.GraphModelLayers module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.model_unit.html#module-UCTB.model_unit.ST_RNN\">6.3.4. UCTB.model_unit.ST_RNN module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.preprocess.html\">6.2. UCTB.preprocess package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#uctb-preprocess-graphgenerator-module\">6.2.1. UCTB.preprocess.GraphGenerator module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.preprocessor\">6.2.2. UCTB.preprocess.preprocessor module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.preprocess.html#module-UCTB.preprocess.time_utils\">6.2.3. UCTB.preprocess.time_utils module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.train.html\">6.6. UCTB.train package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.EarlyStopping\">6.6.1. UCTB.train.EarlyStopping module</a></li>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.train.html#module-UCTB.train.MiniBatchTrain\">6.6.2. UCTB.train.MiniBatchTrain module</a></li>\n</ul>\n</li>\n<li class=\"toctree-l3\"><a class=\"reference internal\" href=\"UCTB.utils.html\">6.7. UCTB.utils package</a><ul>\n<li class=\"toctree-l4\"><a class=\"reference internal\" href=\"UCTB.utils.html#module-UCTB.utils.multi_threads\">6.7.1. UCTB.utils.multi_threads module</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li class=\"toctree-l2\"><a class=\"reference internal\" href=\"UCTB.html#module-UCTB\">Module contents</a></li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/py-modindex.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Python Module Index &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/>\n \n\n\n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>Python Module Index</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n\n   <h1>Python Module Index</h1>\n\n   <div class=\"modindex-jumpbox\">\n   <a href=\"#cap-u\"><strong>u</strong></a>\n   </div>\n\n   <table class=\"indextable modindextable\">\n     <tr class=\"pcap\"><td></td><td>&#160;</td><td></td></tr>\n     <tr class=\"cap\" id=\"cap-u\"><td></td><td>\n       <strong>u</strong></td><td></td></tr>\n     <tr>\n       <td><img src=\"_static/minus.png\" class=\"toggler\"\n              id=\"toggle-1\" style=\"display: none\" alt=\"-\" /></td>\n       <td>\n       <a href=\"UCTB.html#module-UCTB\"><code class=\"xref\">UCTB</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.dataset.html#module-UCTB.dataset.data_loader\"><code class=\"xref\">UCTB.dataset.data_loader</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.dataset.html#module-UCTB.dataset.dataset\"><code class=\"xref\">UCTB.dataset.dataset</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.evaluation.html#module-UCTB.evaluation.metric\"><code class=\"xref\">UCTB.evaluation.metric</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.AGCRN\"><code class=\"xref\">UCTB.model.AGCRN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.ARIMA\"><code class=\"xref\">UCTB.model.ARIMA</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.ASTGCN\"><code class=\"xref\">UCTB.model.ASTGCN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.DCRNN\"><code class=\"xref\">UCTB.model.DCRNN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.DeepST\"><code class=\"xref\">UCTB.model.DeepST</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.GeoMAN\"><code class=\"xref\">UCTB.model.GeoMAN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.GMAN\"><code class=\"xref\">UCTB.model.GMAN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.GraphWaveNet\"><code class=\"xref\">UCTB.model.GraphWaveNet</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.HM\"><code class=\"xref\">UCTB.model.HM</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.ST_MGCN\"><code class=\"xref\">UCTB.model.ST_MGCN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.ST_ResNet\"><code class=\"xref\">UCTB.model.ST_ResNet</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.STGCN\"><code class=\"xref\">UCTB.model.STGCN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.STMeta\"><code class=\"xref\">UCTB.model.STMeta</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.STSGCN\"><code class=\"xref\">UCTB.model.STSGCN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model.html#module-UCTB.model.XGBoost\"><code class=\"xref\">UCTB.model.XGBoost</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model_unit.html#module-UCTB.model_unit.BaseModel\"><code class=\"xref\">UCTB.model_unit.BaseModel</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model_unit.html#module-UCTB.model_unit.DCRNN_CELL\"><code class=\"xref\">UCTB.model_unit.DCRNN_CELL</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model_unit.html#module-UCTB.model_unit.GraphModelLayers\"><code class=\"xref\">UCTB.model_unit.GraphModelLayers</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.model_unit.html#module-UCTB.model_unit.ST_RNN\"><code class=\"xref\">UCTB.model_unit.ST_RNN</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.preprocess.html#module-UCTB.preprocess.GraphGenerator\"><code class=\"xref\">UCTB.preprocess.GraphGenerator</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.preprocess.html#module-UCTB.preprocess.preprocessor\"><code class=\"xref\">UCTB.preprocess.preprocessor</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.preprocess.html#module-UCTB.preprocess.time_utils\"><code class=\"xref\">UCTB.preprocess.time_utils</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.train.html#module-UCTB.train.EarlyStopping\"><code class=\"xref\">UCTB.train.EarlyStopping</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.train.html#module-UCTB.train.MiniBatchTrain\"><code class=\"xref\">UCTB.train.MiniBatchTrain</code></a></td><td>\n       <em></em></td></tr>\n     <tr class=\"cg-1\">\n       <td></td>\n       <td>&#160;&#160;&#160;\n       <a href=\"UCTB.utils.html#module-UCTB.utils.multi_threads\"><code class=\"xref\">UCTB.utils.multi_threads</code></a></td><td>\n       <em></em></td></tr>\n   </table>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/search.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>Search &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"#\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"#\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>Search</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <noscript>\n  <div id=\"fallback\" class=\"admonition warning\">\n    <p class=\"last\">\n      Please activate JavaScript to enable the search\n      functionality.\n    </p>\n  </div>\n  </noscript>\n\n  \n  <div id=\"search-results\">\n  \n  </div>\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n      <script type=\"text/javascript\" src=\"_static/searchtools.js\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n  \n  <script type=\"text/javascript\">\n    jQuery(function() { Search.loadIndex(\"searchindex.js\"); });\n  </script>\n  \n  <script type=\"text/javascript\" id=\"searchindexloader\"></script>\n   \n\n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/_build/searchindex.js",
    "content": "Search.setIndex({docnames:[\"APIReference\",\"UCTB\",\"UCTB.dataset\",\"UCTB.evaluation\",\"UCTB.model\",\"UCTB.model_unit\",\"UCTB.preprocess\",\"UCTB.train\",\"UCTB.utils\",\"index\",\"md_file/all_results\",\"md_file/installation\",\"md_file/introduction\",\"md_file/predictive_tool\",\"md_file/src/image/README\",\"md_file/static/stable_test\",\"md_file/static/transfer_record\",\"md_file/uctb_group\",\"md_file/urban_dataset\",\"md_file/visualization_tool\",\"modules\",\"update_guide\"],envversion:53,filenames:[\"APIReference.rst\",\"UCTB.rst\",\"UCTB.dataset.rst\",\"UCTB.evaluation.rst\",\"UCTB.model.rst\",\"UCTB.model_unit.rst\",\"UCTB.preprocess.rst\",\"UCTB.train.rst\",\"UCTB.utils.rst\",\"index.rst\",\"md_file/all_results.md\",\"md_file/installation.md\",\"md_file/introduction.md\",\"md_file/predictive_tool.md\",\"md_file/src/image/README.md\",\"md_file/static/stable_test.md\",\"md_file/static/transfer_record.md\",\"md_file/uctb_group.md\",\"md_file/urban_dataset.md\",\"md_file/visualization_tool.md\",\"modules.rst\",\"update_guide.txt\"],objects:{\"\":{UCTB:[1,0,0,\"-\"]},\"UCTB.dataset\":{data_loader:[2,0,0,\"-\"],dataset:[2,0,0,\"-\"]},\"UCTB.dataset.data_loader\":{NodeTrafficLoader:[2,1,1,\"\"]},\"UCTB.dataset.data_loader.NodeTrafficLoader\":{daily_slots:[2,2,1,\"\"],dataset:[2,2,1,\"\"],external_dim:[2,2,1,\"\"],make_concat:[2,3,1,\"\"],station_number:[2,2,1,\"\"],train_closeness:[2,2,1,\"\"],train_y:[2,2,1,\"\"]},\"UCTB.dataset.dataset\":{DataSet:[2,1,1,\"\"]},\"UCTB.dataset.dataset.DataSet\":{MergeIndex:[2,2,1,\"\"],MergeWay:[2,2,1,\"\"],data:[2,2,1,\"\"],merge_data:[2,3,1,\"\"],node_monthly_interaction:[2,2,1,\"\"],node_station_info:[2,2,1,\"\"],node_traffic:[2,2,1,\"\"],time_fitness:[2,2,1,\"\"],time_range:[2,2,1,\"\"]},\"UCTB.evaluation\":{metric:[3,0,0,\"-\"]},\"UCTB.evaluation.metric\":{mae:[3,4,1,\"\"],mape:[3,4,1,\"\"],rmse:[3,4,1,\"\"],smape:[3,4,1,\"\"],trunc_mae:[3,4,1,\"\"],trunc_rmse:[3,4,1,\"\"],trunc_smape:[3,4,1,\"\"]},\"UCTB.model\":{AGCRN:[4,0,0,\"-\"],ARIMA:[4,0,0,\"-\"],ASTGCN:[4,0,0,\"-\"],DCRNN:[4,0,0,\"-\"],DeepST:[4,0,0,\"-\"],GMAN:[4,0,0,\"-\"],GeoMAN:[4,0,0,\"-\"],GraphWaveNet:[4,0,0,\"-\"],HM:[4,0,0,\"-\"],STGCN:[4,0,0,\"-\"],STMeta:[4,0,0,\"-\"],STSGCN:[4,0,0,\"-\"],ST_MGCN:[4,0,0,\"-\"],ST_ResNet:[4,0,0,\"-\"],XGBoost:[4,0,0,\"-\"]},\"UCTB.model.AGCRN\":{AGCRN:[4,1,1,\"\"]},\"UCTB.model.ARIMA\":{ARIMA:[4,1,1,\"\"]},\"UCTB.model.ARIMA.ARIMA\":{adf_test:[4,5,1,\"\"],get_order:[4,3,1,\"\"],predict:[4,3,1,\"\"]},\"UCTB.model.ASTGCN\":{ASTGCN_submodule:[4,1,1,\"\"],Spatial_Attention_layer:[4,1,1,\"\"],cheb_conv:[4,1,1,\"\"],cheb_conv_withSAt:[4,1,1,\"\"],cheb_polynomial:[4,4,1,\"\"],make_model:[4,4,1,\"\"]},\"UCTB.model.ASTGCN.ASTGCN_submodule\":{forward:[4,3,1,\"\"]},\"UCTB.model.ASTGCN.Spatial_Attention_layer\":{forward:[4,3,1,\"\"]},\"UCTB.model.ASTGCN.cheb_conv\":{forward:[4,3,1,\"\"]},\"UCTB.model.ASTGCN.cheb_conv_withSAt\":{forward:[4,3,1,\"\"]},\"UCTB.model.DCRNN\":{DCRNN:[4,1,1,\"\"]},\"UCTB.model.DCRNN.DCRNN\":{build:[4,3,1,\"\"]},\"UCTB.model.DeepST\":{DeepST:[4,1,1,\"\"]},\"UCTB.model.DeepST.DeepST\":{build:[4,3,1,\"\"]},\"UCTB.model.GMAN\":{GMAN:[4,4,1,\"\"],STEmbedding:[4,4,1,\"\"],alias_draw:[4,4,1,\"\"],alias_setup:[4,4,1,\"\"],gatedFusion:[4,4,1,\"\"],spatialAttention:[4,4,1,\"\"],temporalAttention:[4,4,1,\"\"],transformAttention:[4,4,1,\"\"]},\"UCTB.model.GeoMAN\":{GeoMAN:[4,1,1,\"\"],input_transform:[4,4,1,\"\"],split_timesteps:[4,4,1,\"\"]},\"UCTB.model.GeoMAN.GeoMAN\":{build:[4,3,1,\"\"]},\"UCTB.model.GraphWaveNet\":{gwnet:[4,1,1,\"\"]},\"UCTB.model.HM\":{HM:[4,1,1,\"\"]},\"UCTB.model.HM.HM\":{predict:[4,3,1,\"\"]},\"UCTB.model.STGCN\":{build_model:[4,4,1,\"\"],cheb_poly_approx:[4,4,1,\"\"],fully_con_layer:[4,4,1,\"\"],gconv:[4,4,1,\"\"],gen_batch:[4,4,1,\"\"],layer_norm:[4,4,1,\"\"],output_layer:[4,4,1,\"\"],spatio_conv_layer:[4,4,1,\"\"],st_conv_block:[4,4,1,\"\"],temporal_conv_layer:[4,4,1,\"\"],variable_summaries:[4,4,1,\"\"]},\"UCTB.model.STMeta\":{STMeta:[4,1,1,\"\"]},\"UCTB.model.STMeta.STMeta\":{build:[4,3,1,\"\"]},\"UCTB.model.STSGCN\":{construct_adj:[4,4,1,\"\"],gcn_operation:[4,4,1,\"\"],get_adjacency_matrix:[4,4,1,\"\"],output_layer:[4,4,1,\"\"],position_embedding:[4,4,1,\"\"],sthgcn_layer_individual:[4,4,1,\"\"],sthgcn_layer_sharing:[4,4,1,\"\"],stsgcl:[4,4,1,\"\"],stsgcm:[4,4,1,\"\"],stsgcn:[4,4,1,\"\"]},\"UCTB.model.ST_MGCN\":{ST_MGCN:[4,1,1,\"\"]},\"UCTB.model.ST_MGCN.ST_MGCN\":{build:[4,3,1,\"\"]},\"UCTB.model.ST_ResNet\":{ST_ResNet:[4,1,1,\"\"]},\"UCTB.model.ST_ResNet.ST_ResNet\":{build:[4,3,1,\"\"]},\"UCTB.model.XGBoost\":{XGBoost:[4,1,1,\"\"]},\"UCTB.model.XGBoost.XGBoost\":{fit:[4,3,1,\"\"],predict:[4,3,1,\"\"]},\"UCTB.model_unit\":{BaseModel:[5,0,0,\"-\"],DCRNN_CELL:[5,0,0,\"-\"],GraphModelLayers:[5,0,0,\"-\"],ST_RNN:[5,0,0,\"-\"]},\"UCTB.model_unit.BaseModel\":{BaseModel:[5,1,1,\"\"]},\"UCTB.model_unit.BaseModel.BaseModel\":{build:[5,3,1,\"\"],close:[5,3,1,\"\"],fit:[5,3,1,\"\"],load:[5,3,1,\"\"],load_event_scalar:[5,3,1,\"\"],predict:[5,3,1,\"\"],save:[5,3,1,\"\"]},\"UCTB.model_unit.DCRNN_CELL\":{DCGRUCell:[5,1,1,\"\"]},\"UCTB.model_unit.DCRNN_CELL.DCGRUCell\":{call:[5,3,1,\"\"],compute_output_shape:[5,3,1,\"\"],output_size:[5,2,1,\"\"],state_size:[5,2,1,\"\"]},\"UCTB.model_unit.GraphModelLayers\":{GAL:[5,1,1,\"\"],GCL:[5,1,1,\"\"]},\"UCTB.model_unit.GraphModelLayers.GAL\":{add_ga_layer_matrix:[5,5,1,\"\"],add_residual_ga_layer:[5,5,1,\"\"],attention_merge_weight:[5,5,1,\"\"]},\"UCTB.model_unit.GraphModelLayers.GCL\":{add_gc_layer:[5,5,1,\"\"],add_multi_gc_layers:[5,5,1,\"\"]},\"UCTB.model_unit.ST_RNN\":{GCLSTMCell:[5,1,1,\"\"]},\"UCTB.preprocess\":{GraphGenerator:[6,0,0,\"-\"],preprocessor:[6,0,0,\"-\"],time_utils:[6,0,0,\"-\"]},\"UCTB.preprocess.GraphGenerator\":{GraphGenerator:[6,1,1,\"\"],scaled_Laplacian_ASTGCN:[6,4,1,\"\"],scaled_laplacian_STGCN:[6,4,1,\"\"]},\"UCTB.preprocess.GraphGenerator.GraphGenerator\":{AM:[6,2,1,\"\"],LM:[6,2,1,\"\"],adjacent_to_laplacian:[6,5,1,\"\"],correlation_adjacent:[6,5,1,\"\"],distance_adjacent:[6,3,1,\"\"],haversine:[6,5,1,\"\"],interaction_adjacent:[6,5,1,\"\"]},\"UCTB.preprocess.preprocessor\":{MaxMinNormalizer:[6,1,1,\"\"],Normalizer:[6,1,1,\"\"],ST_MoveSample:[6,1,1,\"\"],SplitData:[6,1,1,\"\"],WhiteNormalizer:[6,1,1,\"\"],ZscoreNormalizer:[6,1,1,\"\"],chooseNormalizer:[6,4,1,\"\"]},\"UCTB.preprocess.preprocessor.MaxMinNormalizer\":{inverse_transform:[6,3,1,\"\"],transform:[6,3,1,\"\"]},\"UCTB.preprocess.preprocessor.ST_MoveSample\":{move_sample:[6,3,1,\"\"]},\"UCTB.preprocess.preprocessor.SplitData\":{split_data:[6,5,1,\"\"],split_feed_dict:[6,5,1,\"\"]},\"UCTB.preprocess.preprocessor.WhiteNormalizer\":{inverse_transform:[6,3,1,\"\"],transform:[6,3,1,\"\"]},\"UCTB.preprocess.preprocessor.ZscoreNormalizer\":{inverse_transform:[6,3,1,\"\"],transform:[6,3,1,\"\"]},\"UCTB.preprocess.time_utils\":{is_valid_date:[6,4,1,\"\"],is_work_day_america:[6,4,1,\"\"],is_work_day_china:[6,4,1,\"\"]},\"UCTB.train\":{EarlyStopping:[7,0,0,\"-\"],MiniBatchTrain:[7,0,0,\"-\"]},\"UCTB.train.EarlyStopping\":{EarlyStopping:[7,1,1,\"\"],EarlyStoppingTTest:[7,1,1,\"\"]},\"UCTB.train.EarlyStopping.EarlyStopping\":{__best:[7,2,1,\"\"],__p:[7,2,1,\"\"],__patience:[7,2,1,\"\"],__record_list:[7,2,1,\"\"],stop:[7,3,1,\"\"]},\"UCTB.train.EarlyStopping.EarlyStoppingTTest\":{__best:[7,2,1,\"\"],__p_value_threshold:[7,2,1,\"\"],__record_list:[7,2,1,\"\"],__test_length:[7,2,1,\"\"],stop:[7,3,1,\"\"]},\"UCTB.train.MiniBatchTrain\":{MiniBatchFeedDict:[7,1,1,\"\"],MiniBatchTrain:[7,1,1,\"\"],MiniBatchTrainMultiData:[7,1,1,\"\"]},\"UCTB.train.MiniBatchTrain.MiniBatchFeedDict\":{get_batch:[7,3,1,\"\"],restart:[7,3,1,\"\"],shuffle:[7,5,1,\"\"]},\"UCTB.train.MiniBatchTrain.MiniBatchTrain\":{get_batch:[7,3,1,\"\"],restart:[7,3,1,\"\"],shuffle:[7,5,1,\"\"]},\"UCTB.train.MiniBatchTrain.MiniBatchTrainMultiData\":{get_batch:[7,3,1,\"\"],restart:[7,3,1,\"\"],shuffle:[7,5,1,\"\"]},\"UCTB.utils\":{multi_threads:[8,0,0,\"-\"]},\"UCTB.utils.multi_threads\":{multiple_process:[8,4,1,\"\"]}},objnames:{\"0\":[\"py\",\"module\",\"Python module\"],\"1\":[\"py\",\"class\",\"Python class\"],\"2\":[\"py\",\"attribute\",\"Python attribute\"],\"3\":[\"py\",\"method\",\"Python method\"],\"4\":[\"py\",\"function\",\"Python function\"],\"5\":[\"py\",\"staticmethod\",\"Python static method\"]},objtypes:{\"0\":\"py:module\",\"1\":\"py:class\",\"2\":\"py:attribute\",\"3\":\"py:method\",\"4\":\"py:function\",\"5\":\"py:staticmethod\"},terms:{\"10h\":15,\"10m\":[12,18],\"18m\":[12,18],\"21m\":[12,18],\"7500m\":15,\"89m\":[12,18],\"\\u4e00\\u5171\\u6709428\\u79cdpoi\":16,\"\\u4e09\\u4e2a\\u57ce\\u5e02\\u7684poi\\u6570\\u91cf\\u4e0echeck\":16,\"\\u4e4b\\u95f4\":16,\"\\u5206\\u522b\\u4e3a\\u5de5\\u4f5c\\u65e5\":16,\"\\u5230\":16,\"\\u534a\\u5f84\\u4e3a50km\\u7684poi\\u6570\\u91cf\":16,\"\\u5373\\u6bcf\\u4e2a\\u7ad9\\u70b9\\u6709428\\u7ef4\\u7279\\u5f81\":16,\"\\u5373\\u6bcf\\u4e2a\\u7ad9\\u70b9\\u7684\\u7279\\u5f81\\u7ef4\\u5ea6\\u4e3a48\":16,\"\\u53f3\\u4fa7\\u4e3a\":16,\"\\u5404\\u4e2a\\u81ea\\u884c\\u8f66\\u7ad9\\u70b9\\u9644\\u8fd11km\\u7684checkin\\u603b\\u6570\\u91cf\":16,\"\\u5747\\u503c\":15,\"\\u57ce\\u5e02\":16,\"\\u591a\\u6b21\\u5b9e\\u9a8c\\u7ed3\\u679c\":15,\"\\u5b9e\\u9a8c\\u7f16\\u53f7\":15,\"\\u5de5\\u4f5c\\u65e511707\":16,\"\\u5de5\\u4f5c\\u65e52549\":16,\"\\u5de5\\u4f5c\\u65e56049\":16,\"\\u5de6\\u4fa7\\u4e3a\":16,\"\\u5e73\\u5747\\u8017\\u65f6\":15,\"\\u6309\\u7167\\u5de5\\u4f5c\\u65e5\\u548c\\u8282\\u5047\\u65e5\\u5206\\u5f00\":16,\"\\u65e5\\u5747check\":16,\"\\u65f6\\u95f4\\u8303\\u56f4\":16,\"\\u6682\\u65f6\\u53ea\\u8dd1\\u4e864\\u6b21\":15,\"\\u6700\\u7ec8\\u7ed3\\u679c\":15,\"\\u6807\\u51c6\\u5dee\":15,\"\\u6a21\\u578b\\u7248\\u672c\\u542b\\u4e49\":15,\"\\u6bcf\\u4e2a\\u7ad9\\u70b9\\u7edf\\u8ba1\\u9644\\u8fd11km\\u51fa\\u73b0\\u7684poi\\u7c7b\\u578b\":16,\"\\u6bcf\\u6b21\\u5b9e\\u9a8c\\u8017\\u65f6\":15,\"\\u6bcf\\u6b21\\u5b9e\\u9a8c\\u8017\\u65f6\\u7ea6\":15,\"\\u7c97\\u7565\\u8ba1\\u7b97\\u6240\\u6709\\u7ad9\\u70b9\\u9644\\u8fd11km\\u7684checkin\\u6570\\u91cf\\u603b\\u548c\":16,\"\\u7ea2\\u8272\\u4ee3\\u8868\\u5dee\\u4e8efinetun\":16,\"\\u7eff\\u8272\\u7684\\u70b9\\u8868\\u793atransfer\\u6548\\u679c\\u597d\\u4e8efinetun\":16,\"\\u8282\\u5047\\u65e511358\":16,\"\\u8282\\u5047\\u65e52692\":16,\"\\u8282\\u5047\\u65e55450\":16,\"\\u8282\\u5047\\u65e5\\u768424\\u5c0f\\u65f6checkin\":16,\"\\u8ba1\\u7b97\":16,\"\\u8ba1\\u7b97\\u57ce\\u5e02\\u4e2d\\u5fc3\\u4e3a\\u539f\\u70b9\":16,\"\\u8bad\\u7ec3\\u6837\\u672c\\u6570\\u91cf\":16,\"abstract\":6,\"byte\":18,\"case\":13,\"class\":[2,4,5,6,7,13,18],\"default\":[2,4,5,6,7,19],\"export\":19,\"final\":[5,8,13,18],\"float\":[2,3,4,5,6,7,13],\"function\":[2,4,5,6,8,12,13,18,21],\"import\":[11,13,18,19],\"in\\u6570\\u91cf\":16,\"int\":[2,4,5,6,7,8,13,18],\"long\":13,\"new\":[2,4,7,10,13,18],\"null\":7,\"poi\\u6570\\u91cf\":16,\"public\":[12,18],\"return\":[2,4,5,6,7,8,13],\"rmse\\u503c\":15,\"short\":13,\"static\":[4,5,6,7],\"super\":13,\"true\":[2,4,5,6,7,13,15,18],\"try\":13,\"var\":4,\"while\":18,And:[13,18],Bus:[9,12],For:[7,13,18],Its:[2,7],Los:18,The:[2,4,5,6,7,8,10,12,13,18,19,21],Then:[11,13,18,19,21],There:[7,18],These:[4,10,13],Used:[2,6],Using:[11,13],With:18,__best:7,__init__:[5,11,13],__p:7,__p_value_threshold:7,__patienc:7,__record_list:7,__test_length:7,_build:21,_graph:13,_input:13,_op:13,_output:13,aaai:[4,12],abc:6,abl:[13,18],abnorm:18,about:[9,12,13,18],abov:[13,18],absolut:3,academi:17,accept:[8,13],access:[13,18,19],accord:[4,6,7,13,18],account:13,accus:13,achiev:19,acquir:13,act_func:4,activ:[4,5,11,17,18],adajac:6,adam:4,adamoptim:13,adapt:[4,12,13],add:[4,5,13,21],add_ga_layer_matrix:5,add_gc_lay:5,add_multi_gc_lay:5,add_residual_ga_lay:5,addaptadj:4,added:5,adding:5,addit:18,adf_test:4,adj:4,adjac:[4,6,13,18],adjacent_matrix:[6,13],adjacent_to_laplacian:[6,13],adjust:[2,4],adopt:[13,18],adptiv:13,advanc:9,affect:18,after:[4,5,11,13,21],against:13,agcrn:[0,1,10,12,20],agcrncel:4,aggreg:[5,18],alajali:13,algorithm:[4,13],alia:4,alias_draw:4,alias_setup:4,align:13,all:[2,4,6,8,13,15,18],allow:[12,19],almost:5,along:19,alpha:5,alreadi:[11,18],also:[2,5,6,12,13,18],although:18,alwai:13,america:6,among:[8,13,18],anaconda:9,analysi:[4,13,18],analyt:13,angel:18,ani:[13,19],anoth:18,anyth:6,api:[4,9,13,18],apidoc:21,app:19,appear:13,append:[5,7,13],applehelp:21,appli:18,applic:[10,12,18],appreci:12,approxim:[4,5],apr:16,april:[13,17],aptinit:4,arbitrari:2,architectur:[11,13],archiv:18,area:[13,18],arg:[5,10,13],argu:4,argument:[13,18],arima:[0,1,10,12,20],arma:4,around:18,arrai:[6,13,18],arrang:2,array_lik:4,articl:4,arxiv:10,as_default:13,assist:[17,18,19],associ:17,assum:[13,18],astgcn:[0,1,12,20],astgcn_submodul:4,astyp:13,attach:4,attenion:13,attent:[4,5,12,13],attention_merge_weight:5,attet:13,attribut:[2,4,18],aug:17,augment:4,author:18,auto:5,auto_load_model:5,autom:17,automat:5,autoregress:[4,13],avail:18,averag:[2,4,7,13],avoid:11,awesom:12,axi:[4,13],bachelor:17,back:[11,12,13,18],backend:11,bai:[10,12,13,18],base:[2,4,5,6,7,11,12,13],basemodel:[0,1,4,13,20],basi:[13,18],basic:[2,13,18],basiclstmcel:13,batch:[4,5,7,13],batch_siz:[3,4,5,7,10,13],batchsiz:15,becaus:[13,18],been:18,befor:[5,13],begin:[13,18],beij:10,being:[13,18],bellow:18,below:[11,18],benchmark:9,best:[7,10],better:[7,13,19],between:[2,6,18],bia:5,bidirect:13,big:[17,21],bigger:4,bike:[4,9,12,13],bike_chicago:10,bike_dc:10,bike_nyc:10,binar:6,block:[4,13],blog:4,bn_decai:4,bold:10,bool:[2,4,5,6,7],boost:[4,13],both:[4,5,12,13],box:12,build:[2,4,5,6,9,11,12,21],build_instal:11,build_model:4,build_uctb_dataset:18,built:[4,18],bus:18,c_0:4,c_in:4,c_out:4,cach:5,cache_volum:5,calcul:[4,6,13],call:[5,6,7,13],callabl:4,can:[2,4,5,6,7,10,11,12,13,18,19,21],candid:18,cannot:11,capitalbikeshar:18,captur:[4,13],castleliang:[4,13],catalog:18,caus:18,cdw:10,cell:5,censu:[12,18],certain:[2,6],cgrnn:12,chai:17,chang:[2,4,6,7,11,13],channel:[4,5],characterist:6,chargest:10,chargestation_beij:10,chart:[12,19],cheb_conv:4,cheb_conv_withsat:4,cheb_k:4,cheb_poly_approx:4,cheb_polynomi:4,chebyshev:[4,5],check:[7,9,13,18],chen:[13,17],chengdu:10,chenliyue2019:17,chi:18,chicago:[10,12,18],china:[6,17],chines:17,chongq:10,choos:[4,6,13,18],choosenorm:6,chose:13,circl:6,citi:[2,6,10,12,13,15,17,18],citibikenyc:18,cityofnewyork:18,citywid:[4,13],cl_decay_step:4,clarifi:18,classic:13,click:19,clip:4,clone:[11,19],close:[2,4,5,6,10,12],closeness_featur:[4,13],closeness_len:[2,4,6,13],closenss:6,cmap:13,cmd:21,cnn:12,code:[4,5,8,10,11,13,18,19,21],code_vers:[4,5,13],codevers:15,coeffici:6,collect:18,com:[4,11,17,18,19],combin:[8,11,12,13,19],come:18,command:11,commonli:13,commonmark:21,commun:[12,18],compar:13,compat:[11,18],complet:13,complex:18,compon:[4,13,19],compos:[4,6,13],comprehens:18,comput:[3,4,6,11,12,17,18],compute_output_shap:5,con:10,concat:4,concaten:[2,6,13],conclus:10,concret:13,conda:11,conduct:[10,13,18],confid:17,config:[4,13],confirm:19,conflict:11,conform:18,connect:[4,12],consecut:[2,4,6,13],consid:[13,18],considerd:4,consist:[2,4,6,7,13],constant:13,constantli:18,construct:[2,4,12,13],construct_adj:4,constructor:13,contain:[2,4,13,18],content:20,continu:13,contrib:13,contribut:[9,18],contribute_data:2,contributor:9,conv_filt:[4,10],converg:13,convert:[6,18],convolut:[4,5,13],coordin:2,copi:21,copyright:11,correl:[4,6,10,13,15],correlation_adjac:6,correspond:[4,5,6,13,18,19,21],cosin:16,could:[11,18],count:[12,13,18],counti:18,creat:[2,11,13,19],credit:11,crop:4,crowd:[4,12,13],cse:17,csr_matrix:4,css:19,csv:4,cu100:11,cuda:11,cudatoolkit:11,cug:17,cui:17,cuizhenyu18:17,cummin:13,current:[4,5,7,9,12,18],custom:[4,13,19],customizeddemo:13,cut:8,dai:[2,4,6,13,18],daili:[4,13],daily_slot:[2,6],data:[2,3,4,5,6,7,8,10,12,13,17,18,19],data_dir:[2,13],data_list:8,data_load:[0,1,4,6,13,18,20],data_path:18,data_rang:[2,10,13],datafram:4,dataload:[2,18],datarang:15,dataset:[0,1,4,5,6,9,12,15,20],dataset_nam:18,datast:9,datatyp:2,date:6,date_str:6,datetim:6,davidham3:[4,13],dayofweek:4,dcg:10,dcgrucel:5,dchai:17,dcrnn:[0,1,10,12,20],dcrnn_cell:[0,1,20],debug:4,dec:18,decemb:18,decid:7,decim:6,decis:13,decod:[4,13],deep:[4,5,11,13,17],deepst:[0,1,12,20],def:13,default_graph:4,defin:[4,13],definit:6,degre:[4,6,17],demamd:18,demand:[4,12,13,18],demonstr:13,denorm:[6,13],dens:[4,13,18],denseunit:15,depart:17,depend:[4,13,19],depth:[4,10],describ:[4,13,18],descript:18,deseri:18,design:[11,13,18],desir:13,detail:[4,9,12,13,18],detector:18,determin:5,develop:19,devhelp:21,deviat:6,devic:[4,15],diagnosi:[12,19],dickei:4,dict:[2,4,5,6,7,13,18],dictionari:[6,7,18],didi:[8,10],didi_chengdu:10,didi_xian:10,diffcult:18,differ:[4,6,8,13],differenc:4,diffus:[4,13],digit:18,dilat:4,dilation_channel:4,dim:[4,18],dimens:[2,4,6,7,18],direct:16,directli:[2,7],directori:[2,4,5,13,18],dis_matrix:13,disabl:5,discard:18,discret:[4,18],disk:[5,18],dist:11,distacn:6,distanc:[2,4,6,10,13,15],distance_adjac:6,distance_df_filenam:4,distribut:[4,8,18],distribute_list:8,div:19,divid:[4,6,7,13],divis:13,divvybik:18,dnn:[4,13],doc:11,docstr:21,document:12,doe:[4,18],domain:[4,13],download:[11,18],downstream:18,downtown:18,draw:4,driven:[4,10,13],drop:4,drop_out:4,dropdown:19,dropoff:18,dropout:4,dropout_r:4,dtype:[5,13],due:[11,18],dump:18,duplic:18,dure:[2,6,18],dynam:[4,13],dynamic_batch:4,dynamic_rnn:13,each:[4,6,7,8,13,18],earli:[4,5,7,13,18],earlier:2,early_stop_length:5,early_stop_method:5,early_stop_pati:5,earlystop:[0,1,5,20],earlystoppingttest:7,earth:6,easi:[4,13],edg:4,edu:[4,17],effect:[13,19],effici:4,effort:13,either:13,element:[6,18],els:[5,13],email:17,embed:[2,4],embed_dim:4,embedding_s:4,empir:13,emploi:13,empti:2,enabl:19,encod:[4,13],encompass:18,encourag:11,end:[2,4,13,18],end_channel:4,engin:17,enjoi:11,enough:7,enrich:18,env:11,environ:11,epoch:[5,13,15],epsilon:4,equal:[3,4,5,6,7,18],equip:11,error:[3,11,12,13,19],eslength:15,especi:18,estim:18,estimat:10,etc:[12,13,18],euclidean:13,eval_metr:4,evalu:[0,1,4,9,20],evaluate_loss_nam:5,everi:[2,4,6,13],exact:[2,4,6],exampl:[13,18],exce:7,except:[5,13],execut:13,exist:[5,11,13],expand_dim:13,expect:7,experi:[10,11,13],explain:[5,13],explan:15,explicitli:13,exploit:13,explor:13,extend:13,extern:[2,4,13,18],externai_dim:4,external_dim:[2,4,13],external_featur:[4,13],external_feature_weath:18,externalfeatur:18,extra:13,extract:[2,6,10,13,18],f_in:4,f_out:4,fact:[18,21],factor:[4,10,13],faculti:18,fail:[11,13],failur:11,fals:[2,4,5,6,7,13,15],fan:13,fang:17,fangjiangyi2001:17,far:[4,13],feather:18,featur:[2,4,5,6,7,9,18],feb:17,februari:[13,18],fee:18,feed_dict:[6,7],feng:13,few:18,field:18,figur:13,file:[2,4,5,8,10,11,18,19,21],filenam:[4,5],fill:[13,18],filter:4,filter_list:4,final_st:13,find:[11,13],fine:18,finetun:16,finish:[13,18],first:[7,11,13,18,21],firstli:13,fit:[4,5,13,18,19],five:10,fix:[13,18],flag:5,flexibl:12,float32:[5,13],flog:5,flow:[4,9,12,13],folder:11,follow:[10,11,12,13,18,19],forecast:[4,13],forecast_step:[4,13],forget:13,form:[18,21],format:[2,6,12,13,19],former:[2,4,6,13],forward:4,found:[5,10,13,18],four:18,foxmail:17,frame:4,framework:[4,9,13],fratur:4,freeli:18,frequenc:18,from:[2,4,5,6,7,8,11,17,19],fujian:17,full:18,fuller:4,fulli:4,fully_con_lay:4,further:[2,18],fuse:[4,13],fusion:[4,13],futur:[4,13,18],gal:[4,5,10],galhead:15,galunit:15,gate:[4,5,12],gatedfus:4,gbrt:10,gc_output:5,gc_rate:4,gcl:[5,10],gcl_k:4,gcl_l:4,gclstm:4,gclstm_layer:4,gclstmcell:5,gcn:[4,5],gcn_bool:4,gcn_k:[4,5],gcn_l:5,gcn_layer:4,gcn_oper:4,gconv:4,gen_batch:4,gener:[4,6,7,13,21],geng:[4,13],geo:[4,13],geograph:6,geoman:[0,1,12,20],geoscienc:17,ger:13,get:[7,9,11,21],get_a_cel:13,get_adjacency_matrix:4,get_batch:7,get_ord:4,gird_lat_lng:18,git:[11,19],github:[4,11,13,18,19],give:[4,11],given:[4,6],gll:15,global:[4,13],global_featur:4,global_step:5,glu:4,gmail:17,gman:[0,1,10,12,20],gnn:12,goal:13,good:13,got:17,gov:18,gpu:[4,5,9],gpu_devic:[4,5,13],gradient:[4,13],graduat:17,grain:18,granular:[2,9,10,12,13],graph:[2,4,5,6,10,12],graph_merg:4,graph_merge_gal_num_head:4,graph_merge_gal_unit:4,graph_nam:13,graph_obj:13,graphbuild:13,graphgener:[0,1,13,20],graphmodellay:[0,1,20],graphwavenet:[0,1,12,20],great:6,greater:6,grid:[4,12,18],grid_poi:18,gridlatlng:18,gridtrafficload:18,ground:4,groundtruth:13,group:[9,15],gru:4,guo:13,guoshnbjtu:[4,13],gw6p:18,gwnet:4,hail:[4,13],hand:18,handl:[5,13,18],hang:17,hardwar:11,harvard:4,has:[2,18],have:[2,4,6,7,11,18,19],haversin:[6,13],head:[4,5],heapq:13,heatmap:13,height:4,help:[6,11,13,18],here:[11,13,18,21],heurist:13,hidden:[4,5],hidden_dim:4,high:[9,17,18],highest:[4,5],highest_protocol:18,highli:[11,18,19],highlight:10,highwai:18,hip:4,his:17,hisrori:4,histor:[4,18],histori:[2,4,6],hm_obj:13,hmm:12,hmmlearn:13,hoc:13,hoel:13,hold:5,holidai:[6,18],homepag:[11,12,13,17],hong:17,horovod:11,hourli:18,how:[2,4,9,11,12,13],html:[11,19,21],htmlhelp:21,http:[4,11,18,19],huazhong:17,huber:4,hyperparamet:[4,13],hypothesi:7,hyymmmint:17,iclr:12,id_filenam:4,idea:19,ident:7,ieee:10,ignor:4,ijcai:12,ild:6,illustr:13,imag:14,implement:[4,5,9,12,13,19],improv:11,in_arg:6,in_channel:4,in_dim:4,includ:[4,6,11,12,13,18],incorpor:[4,13],ind:13,independ:7,index:[2,4,8],indic:2,individu:4,info:18,inform:[4,5,8,11,13,18],inherit:[5,6,13],init:[4,5,13],init_var:[4,5,13],initi:[4,5,6,13,18],input:[2,4,5,6,7,8,12,13],input_dim:[4,5,13],input_length:4,input_shap:5,input_step:[4,13],input_transform:4,inspect:13,instal:[9,19,21],instanc:[4,13,18],instead:13,instruct:19,insuffici:18,integ:[2,4,8],integr:[12,13,18,19],interact:[2,6,10,12,15,18,19],interaction_adjac:6,interaction_matrix:6,interatct:6,interest:[18,19],interfac:[13,18],intern:7,intersect:13,interv:[7,13,18],introduc:18,introduct:9,inverse_transform:[6,13],is_train:[2,4],is_valid_d:6,is_work_day_america:[2,6],is_work_day_china:6,iter:[4,13,18],its:[2,4,6,11,13],jan:17,januari:18,jiang:13,jiangyi:17,jin:17,jinxu:17,job:8,job_i:8,jsmath:21,jul:17,juli:[13,17],junbo:4,just:[13,18,21],keep:5,keep_prob:4,kei:[6,7,9,13],kera:5,kernal_s:10,kernel:4,kernel_initi:5,kernel_s:[4,10],kind:4,knowledg:[10,12,19],known:11,kong:17,kwarg:[2,4,5,6,13],l_tild:4,lab:17,label:4,laboratori:17,lack:18,lag:4,land:[4,13],lapalac:6,laplac:6,laplace_matrix:13,laplacian:[4,5,6,13],laplacian_matrix:5,larg:18,larger:6,largest:18,last:[4,7,13],lat1:6,lat2:6,lat:18,lat_lng_list:[6,13],late:[4,13],later:2,latest:[2,6,18],latitud:[2,6,18],layer:[4,5,13],layer_norm:4,lead:11,leaky_relu:5,learn:[4,11,13,17],learner:4,least:13,legend:13,leibai:[4,13],len:[4,13,18],len_input:4,len_seq:4,length:[2,4,5,6,7,13,18],lentimeslot:18,less:[2,4,13,18],let:[13,18],level:[4,13],ley:17,leyewang:17,liang:[4,13],librari:[4,11,18,21],licens:11,like:[5,11],likelihood:4,limit:7,lin:13,line:[6,10,12,13,15],linear:13,link:[6,12,18],list:[2,4,5,6,7,8,18],liu:[13,17],liyaguang:[4,13],liyu:17,lng:18,load:[5,9],load_event_scalar:5,loader:[2,13,18,19],local:[4,12,13,18,19,21],local_featur:4,localhost:19,locat:[6,13,18,21],locker:8,log:5,lon1:6,lon2:6,longbiao:17,longbiaochen:17,longitud:[2,6],longtitud:18,look:[11,13,18],loss:[4,5,13],lot:13,low:11,lower:13,lstm:[4,5,10,12,13],lstm_layer:4,lstm_unit:4,lstmc:10,lstmcell:5,lstmunit:15,lucktroi:[4,13],luzern:[12,18],machin:[4,11,13],mae:3,mai:[2,4,11,13,17,18],mail:17,main:[2,18],major:[4,13,17],make:[4,18],make_concat:[2,13],make_model:4,mani:[2,4,5,6,13],map:[4,10,18],mape:[3,15],march:17,mark:[10,13],markdown:21,mask:4,mask_init_valu:4,master:[11,17],matplotlib:[13,18],matric:[4,6],matrix:[4,5,6,13,18],matrx:18,max:[2,4,5,13],max_ar:4,max_d:4,max_depth:[4,13],max_diffusion_step:[4,5],max_epoch:[5,13],max_lag:4,max_ma:4,max_to_keep:[4,5,13],maximum:[4,6],maxminnorm:6,mean:[3,4,6],mechan:[4,13],meet:18,melbourn:[12,18],member:13,memori:[5,13,18],mention:18,menu:19,merg:[4,13,18],merge_data:2,merge_gal_unit:5,mergeindex:[2,10,13,18],mergewai:[2,13,18],meteorolog:[4,13],meter:6,method:[2,4,5,6,7,13],metr:[10,13,18],metr_la:10,metric:[0,1,4,13,20],metro:[9,12,13,15],metro_chongq:10,metro_shanghai:[10,13],metropolitan:18,mgcn:[4,5,10,12],middl:4,might:18,million:18,min:[12,13,18],min_max_denorm:13,min_max_norm:13,mini:5,minibatchfeeddict:7,minibatchtrain:[0,1,20],minibatchtrainmultidata:7,minim:13,minimum:[6,13],minut:[2,12,18],miss:18,mode:4,model:[0,1,2,5,7,9,10,12,19,20],model_dir:[4,5,13],model_obj:13,model_r:4,model_unit:[0,1,4,9,13,20],modifi:[10,13],modul:[0,12,13,18,19,20],module_typ:4,month:[6,18],month_num:2,monthli:2,more:[4,5,8,10,11,12,13,18,19],move:[4,13],move_sampl:6,mta:18,much:18,multi:[4,5,10,13,18],multi_thread:[0,1,20],multipl:4,multiple_process:8,multirnncel:13,must:[4,5,13,21],mxnet:[4,11],my_dataset:18,my_lstm:13,my_model:13,mymodel:13,n_decoder_hidden_unit:4,n_encoder_hidden_unit:4,n_estim:[4,13],n_frame:4,n_hi:4,n_iter:13,n_jo:8,n_job:8,n_node:4,n_rout:4,n_stacked_lay:4,naiv:[4,5],name:[2,4,5,12,13,18,19],nb_block:4,nb_chev_filt:4,nb_predict_step:4,nb_time_filt:4,ndarrai:[2,3,4,5,6,7,18],nearest:13,necessari:[13,18],need:[2,4,5,6,11,13,18,19],neighbor:6,neighborhood:12,neighbour_adjac:13,nerual:13,network:[4,5,12,13,18,19],neural:[2,4,5,6,13],neurip:12,new_valu:7,newaxi:13,newer:11,newest:7,next:[13,21],nine:13,nlargest:13,nni:10,nnzhan:[4,13],node:[2,4,5,6,12,13,18,19],node_monthly_interact:2,node_num:[2,4],node_poi:18,node_satation_info:18,node_station_info:[2,13,18],node_traff:[2,18],nodetrafficload:[2,6,13,18],non:[4,13],none:[2,3,4,5,13],nonetyp:18,norm:4,normal:[2,4,6,13,15],notat:15,note:[2,4,13],noth:5,nov:17,novel:[13,19],novemb:13,now:[2,4,6,11,13,17,18],npm:19,num:[4,18],num_block:4,num_chev_filt:4,num_compon:13,num_conv_filt:4,num_dense_unit:4,num_diffusion_matrix:4,num_featu:5,num_featur:5,num_for_predict:4,num_graph:[4,5,13],num_head:5,num_hidden_unit:4,num_lay:[4,13],num_nod:[4,5,6,13],num_of_featur:4,num_of_filt:4,num_of_timestep:4,num_of_vertic:4,num_proj:5,num_residual_unit:[4,10],num_rnn_lay:4,num_rnn_unit:4,num_stat:13,num_step:4,num_time_filt:4,num_unit:[5,13],number:[2,4,5,6,7,8,10,11,18],numpi:[6,13,18],nvidia:11,nyc:[4,10,12,13,18],nyu:18,obei:18,obj:10,object:[2,4,5,6,7,13,18,19],observ:4,obtain:[6,13,18,19],occur:11,octob:13,offer:[18,19],often:13,ojs:4,onc:7,one:[2,4,5,6,7,8,10,13,18],onli:[4,7,11,13,18],op_nam:5,open:[12,18],opendata:18,oper:[4,13,18],operation1_nam:5,operation2_nam:5,ops:5,optim:[4,5,13],optimizer_nam:4,option:[2,4,18,19],order:[4,5,7,13],org:[4,11],orgin:6,origin:[2,18],other:[2,5,9,13],otherwis:[4,5,6,7,18],othewis:2,our:[5,9,13,18],out_channel:4,out_dim:4,outcom:4,output:[4,5,8,11,13,18],output_activ:4,output_dim:[4,13],output_dir:18,output_lay:4,output_nam:[5,13],output_s:5,output_step:[4,13],output_tensor1_nam:5,output_tensor1_valu:5,output_tensor_name1:5,output_tensor_name2:5,outputs_dict:5,over:18,overal:16,overview:9,overwrit:5,own:[2,5,6,9,19],p_test:13,p_value_threshold:7,packag:[0,9,11,12,13,18,20],page:[11,18],pair:[2,6,7,13],pan:13,panda:13,paper:[4,10,13],param:[2,3,4,5],paramet:[2,3,4,5,6,7,8,10,13],part:[4,8,13],partit:8,partition_func:8,pass:[4,13],past:[9,13,21],path:[2,4,18],patienc:[7,15],pattern:13,pearson:6,pedestrian:[9,12],pedestrian_melbourn:18,peke:17,pem:[10,18],pems_bai:10,percentag:3,perform:[5,13],period:[2,4,6,12],period_featur:[4,13],period_len:[2,4,6,10,13],person:19,perspect:13,phase:13,php:4,pickl:[2,18],pickup:18,piec:[2,4,6,13],pip:[11,21],pkl:18,pkl_file_nam:18,pku:17,place:18,placehold:[4,13],pleas:11,plot:[13,18],pls:8,plt:[13,18],poi:18,point:[4,6,13,18],polynomi:[4,5],popular:13,portal:18,posit:[2,6],position_embed:4,possibl:18,postgradu:17,potenti:11,practic:18,pred:13,pred_step:4,predict:[2,3,4,5,6,9,18],predict_length:4,prediction_test:13,prefix:4,prepar:18,preprocess:[0,1,9,13,18,20],preprocessor:[0,1,13,20],presenc:4,present:4,preserv:18,preset:13,previou:4,principl:18,print:[5,13,18],print_dataset:18,prior:12,privaci:18,prob:4,probabl:[13,18],problem:[11,13],procedur:18,process:[2,4,6,8,13,18],professor:17,project:[9,11,18],prompt:19,proper:[6,18],properti:[4,13],proport:2,propos:18,protocol:18,provid:[5,12,13,18,19],proxim:[10,12],public_dataset:18,pull:19,put:[13,18],pyindex:11,pyplot:[13,18],python:[5,10,11,13,18],pytorch:[4,11,13],qthelp:21,question:11,quick:9,quickstart:[4,11,13],random:13,rang:[2,12,13,18],raster:18,rate:4,ratio:[2,4,6,16],ratio_list:6,ration:5,raw:[6,13,18],read:18,readm:11,real:18,real_denorm:13,realiz:13,recent:13,recognit:13,recommend:[11,18,19],recommonmark:21,record:[2,4,6,7,10,13,18],recurr:[4,5,13],red:13,redefin:13,reduc:[8,13],reduce_func:8,reduce_mean:13,ref:4,refer:[4,8,9,11,13,19],reg:[4,13],region:13,regular:5,regularli:18,rel:2,relat:[13,21],releas:[5,12,18],relu:4,remov:[2,3,13],replac:3,repo:12,report:11,repositori:[4,12,13,18,19],repres:6,represent:5,request:19,requir:[13,19],research:18,reserv:4,reshap:13,residu:[4,5,13],residual_channel:4,residual_unit:10,resnet:[4,10,12],resourc:14,respect:[10,13,18],restart:7,restor:[6,18],result:[2,4,5,9,11,13,16,18],retain:18,retrun:4,return_output:5,reus:5,revers:13,rho:4,ride:[4,12,13,18],ridership:18,rideshar:12,rmse:[3,4,13,15],rnn:[4,5,12,13],rnn_cell:13,rnn_cell_impl:5,rnncell:5,road:[12,18],root:[3,4,13],rout:[4,18],rtcat:21,rtd:21,run:[10,13,18,19,21],runtim:11,s_rmse:3,sai:18,same:[2,3,4,5,6,12,13,18],sampl:[4,7,13],sarima:12,save:[4,5,18],save_model:5,save_model_nam:5,saver:5,scalar:5,scalar_nam:5,scale:[4,6,18],scaled_laplacian_astgcn:6,scaled_laplacian_stgcn:6,scenario:18,schedul:13,schmidhub:13,scienc:17,scipi:4,scope:[4,19],score:4,scratch:7,screen:19,script:[13,18,19],sea:4,seaborn:13,season:[4,13],seasonal_ord:[4,13],second:[2,18,21],secondari:21,section:[12,13,18,21],see:[2,4,7,12,13,19],seen:18,select:[2,6,13,18,19],self:[2,6,13],send:8,sens:17,sensor:[4,12,13,18],sensori:[4,13],sep:17,sept:16,seq_len:4,sequenc:[4,5,18],sequence_length:[5,6,7,13],seri:[4,13],serial:[4,18],serializinghtml:21,serv:19,session:[5,7],set:[2,4,5,7,10,13,18],setup:11,seven:[2,4,6],sever:[7,11],sgd:4,shahabi:13,shall:2,shanghai:[10,13,15],shanghaiv1:15,shape:[2,3,4,5,6,13,18],share:[4,12,18],share_queu:8,shawnwang:[4,13],shortest:13,should:[2,4,5,6,7,8,13,18],show:[10,12,13,18,19],shown:[13,18],shuffl:[4,5,7],shuffle_data:5,side:7,sigmoid:4,sigspati:12,silent:4,similar:[2,4,12,13,16],simpl:[4,13],simpli:[4,13],simplifi:18,sinc:[4,13],singl:[2,4],site:18,situat:[11,13,18],six:18,size:[4,5,7,18],skip:[4,11],skip_channel:4,slot:[2,4,6,13,18],small:[7,18],smaller:[3,6,7],smape:3,smart:17,snowbridg:17,sns:13,softmax:5,softwar:17,solut:11,some:[11,12,18,21],song:13,sort:2,sourc:[11,12,19],span:[7,10,18],spars:[4,18],spatial:[4,5,10,12,13,18],spatial_attent:4,spatial_attention_lay:4,spatial_emb:4,spatialattent:4,spatio:[4,13,18],spatio_conv_lay:4,spatiotempor:[4,12,13,19],special:18,specif:[11,12,18,19],specifi:[2,4,5,6,10,13,18],spectral:4,speed:[9,12,13],sphinx:21,sphinxcontrib:21,split:[2,4,6,13],split_data:6,split_feed_dict:6,split_timestep:4,splitdata:[6,13],splite:13,sqrt:13,squar:[3,13],squarederror:[4,13],st0:15,st_conv:4,st_conv_block:4,st_map:13,st_method:4,st_mgcn:[0,1,12,20],st_movesampl:6,st_resnet:[0,1,5,10,12,20],st_rnn:[0,1,20],st_sim1_0:15,st_sim_0:15,stack:4,stacked_cel:13,stacked_output:13,stackoverflow:11,standard:[4,6],start:[2,9,11,18],state:[5,12,13,18],state_is_tupl:13,state_s:5,statement:13,station:[2,4,10,13,18],station_index:13,station_numb:[2,13],stationari:18,stationinfo:[2,18],statist:[13,18],statsmodel:13,statt:4,statu:18,ste:4,ste_p:4,ste_q:4,stembed:4,step:[2,4,5,6,11,13,19],stgcn:[0,1,10,12,20],sthgcn_layer_individu:4,sthgcn_layer_shar:4,still:18,stitch:13,stmeta:[0,1,5,10,12,15,20],stmeta_obj:[10,13],stmeta_obj_topk:13,stmeta_v0:10,stmeta_v1:[10,13],stmeta_v2:10,stmeta_v3:10,stop:[5,7,13,18],store:[2,4,5,6],str:[2,4,5,6],stream:[2,18],stride:[4,13],string:[2,4,5,6],strnn:4,strongli:18,structur:[4,12,13],stsgcl:4,stsgcm:4,stsgcn:[0,1,12,20],sttp:18,stu:17,student:17,style:19,subclass:13,subpackag:20,subscript:5,subset:6,substitut:18,suburb:18,subwai:18,success:9,successfulli:[11,21],sum:[2,13,18],summar:18,summari:4,supplementari:2,support:[4,5,9,12],sym:4,symmetr:3,synchron:[4,13],system:[10,13,18],t_0:4,t_in:4,t_out:4,tabl:[18,21],tail:7,take:[7,13,18],tanh:[4,5],target:[3,4,6,7,13],target_len:4,target_length:[2,6,13],target_nod:13,target_nodz:13,target_st:13,task:[4,8,12,13,18],task_func:8,taxi:[9,12],tcn:12,tech:[4,13],techniqu:[5,12],technolog:17,temperatur:4,templat:[18,19],tempor:[2,4,5,6,10,12,18],temporal_conv_lay:4,temporal_emb:4,temporal_merg:4,temporal_merge_gal_num_head:4,temporal_merge_gal_unit:4,temporalattent:4,temporam:4,tengfei:17,tensor:[4,5,13],tensorboard:[4,5],tensorflow:[4,5,11,13],term:13,test:[2,4,5,7],test_clos:[2,13],test_ef:13,test_i:[2,13],test_period:[2,13],test_predict:13,test_prediction_collector:13,test_ratio:[2,13],test_rms:13,test_sequence_len:13,test_trend:[2,13],test_x:13,text:21,tf66366:17,than:[2,3,4,6,7,13,18],thank:11,thei:[7,13],them:[6,11,13,18],theme:21,theoret:13,therefor:13,theta:4,thi:[4,5,6,7,10,11,12,13,18,21],thing:21,those:7,thread:8,three:[4,8,13,18],threshold:[3,6,7,13,15],threshold_correl:[6,13],threshold_dist:[6,13],threshold_interact:[6,13],threshold_neighbour:13,through:[13,18,19],thu:[5,11,18],till:17,time:[2,4,6,7,10,12,13,18],time_fit:[2,6,18],time_index:13,time_rang:[2,18],time_sequ:[4,13],time_seri:4,time_slot_num:[2,4],time_step:4,time_strid:4,time_util:[0,1,20],timefit:[2,18],timeofdai:4,timerang:[2,18],timespan:18,timestep:[4,13],titl:[13,21],tkde:12,tlc:18,tmeta:10,tmp_dir:18,togeth:6,toi:13,too:2,tool:9,toolbox:[11,12],toolkit:10,top:[10,13],topk:13,topkgraph:13,torch:[4,11],torch_stabl:11,torchvis:11,total:[4,13,18],total_sens:4,tract:[12,18],trafalgar2001:17,traffic:[2,4,12,13,18],traffic_data:[6,13],traffic_data_index:13,traffic_grid:18,traffic_monthly_interact:18,traffic_nod:18,trafficgrid:18,trafficmonthlyinteract:[2,18],trafficnod:[2,18],train:[0,1,2,4,5,9,15,20],train_clos:[2,13],train_data:13,train_data_length:[2,10,13],train_ef:13,train_i:[2,13],train_loss:13,train_op:[5,13],train_period:[2,13],train_sequence_len:13,train_test_ratio:13,train_time_slot_num:2,train_trend:[2,13],train_x:13,trainabl:[4,5],trainable_var:13,trainbl:13,traindai:15,transfer:[6,16],transform:[4,6,13,18],transformattent:4,transport:[12,18],transpos:13,tree:[4,13,18],trend:[2,4,6,12],trend_featur:[4,13],trend_len:[2,4,6,10,13],trial:[12,19],trick:13,trigger:7,trip:18,trunc_ma:3,trunc_rms:3,trunc_smap:3,truncat:3,truth:4,tsv:19,turn:6,tutori:[5,9,11,12],two:[2,4,6,7,10,13,18,19],type:[2,3,4,5,6,7,11,12,13],type_:4,uca:17,uctb:[0,11,12,19,21],ultim:[13,18],under:13,undergradu:17,uniform:4,uniqu:[4,13],unit:[4,5,13],univari:4,univers:17,unknown:18,unseen:11,unzip:18,updat:[18,21],upgrad:11,upload:[12,19],urban:[9,13],usag:[13,19],use:[2,4,5,10,11,12,18,21],use_bia:5,use_curriculum_learn:4,use_gc_for_ru:5,use_mask:4,used:[2,4,5,6,8,13,18],useful:13,user:[6,11],uses:18,using:[4,5,6,11,18,19],ust:17,utd19:18,util:[0,1,4,9,20],v_name:4,val_loss:[5,13],valid:[4,5,6,13],validate_ratio:[5,13],valu:[4,6,7,13,15,18],variabl:[4,7,13,18],variable_nam:18,variable_summari:4,variou:[12,18],vector:6,vehicl:[12,18],vehicular:13,verbos:[4,5],veritasyin:[4,13],version:[4,5,9,13,18,21],vertic:4,via:[9,13],view:4,vis:11,vision:17,visit:[12,19],visual:[4,9,10,13,18],vmax:13,vmin:13,vstack:13,vue:19,wai:[6,13,18],walk:13,wan:13,wang:[13,17],want:[18,21],wavenet:[4,10,13],weather:18,websit:[12,18,19],week:[2,4,6],weekli:4,weight:[4,5,6],welcom:[12,18,19],well:[11,12,13],wen:13,wenji:17,were:18,what:[11,18],when:[2,4,5,7,11,13,18,21],where:[4,6,8,18],whether:[4,5,7,18],which:[2,4,5,6,8,11,13,18,19],whitenorm:6,whl:11,whole:[5,13],whose:[2,7,13],wide:[13,18],width:4,william:13,wind:4,window:[11,18],with_lm:13,with_tp:[2,4,13],without:[6,13],wjycc:17,won:[6,18],work:[4,11,18],workday_pars:2,worldwid:18,wors:7,worth:13,wrapper:13,www:[11,18],x_denorm:13,x_normal:13,x_train:6,xavier:4,xgboost:[0,1,10,12,20],xiamen:17,xian:10,xie:17,xiuhuai:17,xlabel:13,xmu:17,xplore:10,xueqiao:17,xxx:11,xxxx:19,y_pred:13,y_truth:13,yaguang:4,yaml:11,yang:[13,17],yao:13,yayao:17,year:18,yin:13,ylabel:13,yml:[10,13],york:[10,13,18],yoshal:[4,13],you:[5,6,11,12,13,18,19,21],your:[2,5,6,9,11,12,19],yourowncompon:19,yuxuan:4,yyyi:[2,18],zero:[13,18],zhang:[4,13],zheng:13,zhengchuanpan:4,zhenyu:17,zhihu:4,zhou:13,zhu:[13,17],zhuanlan:4,zhuhang:17,zip:18,zone:18,zscorenorm:6},titles:[\"6. API Reference\",\"UCTB package\",\"6.1. UCTB.dataset package\",\"6.5. UCTB.evaluation package\",\"6.4. UCTB.model package\",\"6.3. UCTB.model_unit package\",\"6.2. UCTB.preprocess package\",\"6.6. UCTB.train package\",\"6.7. UCTB.utils package\",\"Welcome to UCTB\\u2019s documentation!\",\"7. Benchmark\",\"2. Installation\",\"1. Introduction\",\"4. Predictive Tool\",\"&lt;no title&gt;\",\"Stable Test Records\",\"Check-In\\u4e0ePOI\\u6570\\u636e\\u5904\\u7406\\u65b9\\u6cd5\",\"8. About us (UCTB Group)\",\"3. Urban Datasets\",\"5. Visualization-tool\",\"UCTB\",\"&lt;no title&gt;\"],titleterms:{\"\\u4f7f\\u7528check\":16,\"\\u4f7f\\u7528poi\\u4fe1\\u606f\\u8fdb\\u884c\\u76f8\\u4f3c\\u7ad9\\u70b9\\u5339\\u914d\":16,\"\\u5206\\u6790transfer\\u6548\\u679c\\u5728\\u57ce\\u5e02\\u4e2d\\u7684\\u5206\\u5e03\":16,\"\\u6570\\u636e\\u8be6\\u60c5\":16,\"\\u7279\\u5f81\\u76f8\\u4f3c\\u5ea6\\u65b9\\u6cd5\":16,\"\\u7279\\u5f81\\u8ba1\\u7b97\\u65b9\\u6cd5\":16,\"in\\u4e0epoi\\u6570\\u636e\\u5904\\u7406\\u65b9\\u6cd5\":16,\"in\\u6570\\u636e\\u8fdb\\u884c\\u76f8\\u4f3c\\u7ad9\\u70b9\\u7684\\u5339\\u914d\":16,\"poi\\u7279\\u5f81\\u8ba1\\u7b97\\u65b9\\u6cd5\":16,Bus:18,Use:[13,18],about:17,advanc:13,agcrn:[4,13],anaconda:11,api:0,arima:[4,13],astgcn:[4,13],basemodel:5,beij:15,benchmark:10,bike:[10,18],build:[13,15,18],chargest:15,check:[11,16],chengdu:15,chicago:16,citi:16,close:13,content:1,contribut:19,contributor:17,current:13,data_load:2,dataset:[2,10,13,18,19],datast:12,dcrnn:[4,13],dcrnn_cell:5,deepst:[4,13],definit:13,detail:10,didi:15,document:9,earlystop:7,electr:10,evalu:[3,13],featur:13,flow:18,format:18,framework:11,from:[13,18],full:13,geoman:[4,13],get:18,gman:[4,13],gpu:11,granular:18,graph:[13,15],graphgener:6,graphmodellay:5,graphwavenet:[4,13],ground:19,group:17,hidden:13,high:11,histor:13,hmm:13,how:18,implement:10,inform:19,instal:11,introduct:12,kei:17,kind:13,knowledg:13,load:[13,18],make:13,markov:13,mean:13,metric:3,metro:[10,18],mgcn:13,minibatchtrain:7,minut:10,model:[4,13,15],model_unit:5,modul:[1,2,3,4,5,6,7,8],multi_thread:8,multipl:13,nyc:16,other:18,our:19,overview:18,own:[13,18],packag:[1,2,3,4,5,6,7,8],paramet:15,passeng:10,past:17,pedestrian:18,period:13,predefin:19,predict:[10,12,13,19],preprocess:6,preprocessor:6,project:19,quick:[13,19],record:15,refer:0,regress:13,resnet:13,result:10,ride:10,search:10,share:10,singl:13,space:10,spatial:19,speed:[10,18],st_mgcn:4,st_resnet:4,st_rnn:5,stabl:15,start:[13,19],stgcn:[4,13],stmeta:[4,13],stsgcn:[4,13],subpackag:1,success:11,support:[11,13],target:16,task:10,taxi:18,tempor:[13,19],test:[13,15],time_util:6,tool:[12,13,19],traffic:10,train:[7,13],trend:13,truth:19,tutori:13,uctb:[1,2,3,4,5,6,7,8,9,13,17,18,20],urban:[12,18],urban_dataset:13,use:13,using:13,util:8,vehicl:10,version:11,via:11,visual:[12,19],welcom:9,well:19,xgboost:[4,13],xian:15,your:[13,18]}})"
  },
  {
    "path": "docs/sphinx/_build/update_guide.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>&lt;no title&gt; &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>&lt;no title&gt;</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/update_guide.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <p>The first thing is to install the UCTB library, in fact, if you want to update successfully, you must first install the UCTB library successfully。</p>\n<p>The second thing to do is to install the Sphinx-related library functions locally. Here are some of the related versions。\npip install Sphinx==5.1.1\npip install sphinx-markdown-tables==0.0.17\npip install sphinx-rtd-theme==1.2.1\npip install sphinxcontrib-applehelp==1.0.2\npip install sphinxcontrib-devhelp==1.0.2\npip install sphinxcontrib-htmlhelp==2.0.0\npip install sphinxcontrib-jsmath==1.0.1\npip install sphinxcontrib-qthelp==1.0.3\npip install sphinxcontrib-serializinghtml==1.1.5\npip install rtcat-sphinx-theme==0.1.1\npip install recommonmark==0.7.1\npip install commonmark==0.9.1\npip install sphinx-markdown-tables==0.0.17</p>\n<p>Next, locate the.md file that corresponds to the section you want to update,\nIf you want to add text, just copy and paste it, if you want to add a big title, you can use the form of a # title, if you want to add a secondary title, you can use the form of a ## title, and so on.</p>\n<p>When update docstrings, run this code in cmd:\nsphinx-apidoc -o . ../../UCTB\nsphinx-build -b html . ..\nsphinx-build -b html . _build\nThen you can get the html file generated after the update.</p>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/sphinx/conf.py",
    "content": "# Configuration file for the Sphinx documentation builder.\n#\n# This file only contains a selection of the most common options. For a full\n# list see the documentation:\n# http://www.sphinx-doc.org/en/master/config\n\n# -- Path setup --------------------------------------------------------------\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#\nimport os\nimport sphinx_rtd_theme\nimport sys\nsys.path.insert(0, os.path.abspath('../../'))\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#\n# needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx.ext.autodoc',\n    'sphinx.ext.doctest',\n    'sphinx.ext.intersphinx',\n    'sphinx.ext.todo',\n    'sphinx.ext.coverage',\n    'sphinx.ext.mathjax',\n    'sphinx.ext.githubpages',\n    'sphinx.ext.napoleon',\n    'sphinx_markdown_tables',\n    'recommonmark'\n]\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n#\n# source_parsers = {\n#    '.md': 'recommonmark.parser.CommonMarkParser',\n# }\nsource_suffix = {\n    '.rst': 'restructuredtext',\n    '.txt': 'markdown',\n    '.md': 'markdown',\n}\n# source_suffix = '.rst'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = 'UCTB'\ncopyright = '2019, UCTB group'\nauthor = 'UCTB group'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = ''\n# The full version, including alpha/beta/rc tags.\nrelease = ''\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This patterns also effect to html_static_path and html_extra_path\nexclude_patterns = []\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = True\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\nhtml_theme = 'rtcat_sphinx_theme'\nimport rtcat_sphinx_theme\nhtml_theme_path = [rtcat_sphinx_theme.get_html_theme_path()]\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#\n# html_theme_options = {}\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\n# Custom sidebar templates, must be a dictionary that maps document names\n# to template names.\n#\n# This is required for the alabaster theme\n# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars\nhtml_sidebars = {\n    '**': [\n        'relations.html',  # needs 'show_related': True theme option to display\n        'searchbox.html',\n    ]\n}\n\n\n# -- Options for HTMLHelp output ------------------------------------------\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'adoc'\n\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n    # The paper size ('letterpaper' or 'a4paper').\n    #\n    # 'papersize': 'letterpaper',\n\n    # The font size ('10pt', '11pt' or '12pt').\n    #\n    # 'pointsize': '10pt',\n\n    # Additional stuff for the LaTeX preamble.\n    #\n    # 'preamble': '',\n\n    # Latex figure (float) alignment\n    #\n    # 'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n    (master_doc, 'a.tex', 'a Documentation',\n     'a', 'manual'),\n]\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'a', 'a Documentation',\n     [author], 1)\n]\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n    (master_doc, 'a', 'a Documentation',\n     author, 'a', 'One line description of project.',\n     'Miscellaneous'),\n]\n# Example configuration for intersphinx: refer to the Python standard library.\nintersphinx_mapping = {'https://docs.python.org/': None}\n"
  },
  {
    "path": "docs/sphinx/index.rst",
    "content": ".. UCTB documentation master file, created by\n   sphinx-quickstart on Sun Jul 28 23:57:53 2019.\n   You can adapt this file completely to your liking, but it should at least\n   contain the root `toctree` directive.\n\nWelcome to UCTB's documentation!\n================================\n\n.. toctree::\n   :maxdepth: 2\n   :numbered:\n\n   md_file/introduction.md\n\n   md_file/installation.md\n\n   md_file/urban_dataset.md\n\n   md_file/predictive_tool.md\n\n   md_file/visualization_tool.md\n\n   APIReference.rst\n\n   md_file/all_results.md\n\n   md_file/uctb_group.md\n"
  },
  {
    "path": "docs/sphinx/make.bat",
    "content": "@ECHO OFF\n\npushd %~dp0\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset SOURCEDIR=.\nset BUILDDIR=_build\n\nif \"%1\" == \"\" goto help\n\n%SPHINXBUILD% >NUL 2>NUL\nif errorlevel 9009 (\n\techo.\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\n\techo.installed, then set the SPHINXBUILD environment variable to point\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\n\techo.may add the Sphinx directory to PATH.\n\techo.\n\techo.If you don't have Sphinx installed, grab it from\n\techo.http://sphinx-doc.org/\n\texit /b 1\n)\n\n%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\ngoto end\n\n:help\n%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\n\n:end\npopd\n"
  },
  {
    "path": "docs/sphinx/md_file/.gitignore",
    "content": "*$py.class\n*,cover\n*.egg\n*.egg-info/\n*.log\n*.manifest\n*.mo\n*.pot\n*.py[co]\n*.py[cod]\n*.so\n*.spec\n*/.DS_Store\n*~\n.DS_Store\n._.DS_Store\n.Python\n.cache\n.coverage\n.coverage.*\n.eggs/\n.env\n.idea\n*/.idea\n_pycache__/\nbuild/\n*.npy\n.vscode/\n*.pkl\n"
  },
  {
    "path": "docs/sphinx/md_file/all_results.md",
    "content": "#   Benchmark\n\n## Datasets\n\n| Application              |  Bike-sharing   |  Bike-sharing   |  Bike-sharing   |  Ride-sharing   |  Ride-sharing   |      Metro      |      Metro      |       EV        |  Traffic Speed  |  Traffic Speed  |\n| :----------------------- | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |\n| City                     | *New York City* |    *Chicago*    |      *DC*       |     *Xi'an*     |    *Chengdu*    |   *Chongqing*   |   *Shanghai*    |    *Beijing*    |    *METR-LA*    |   *PEMS-BAY*    |\n| Time span                | 2013.03-2017.09 | 2013.07-2017.09 | 2013.07-2017.09 | 2016.10-2016.11 | 2016.10-2016.11 | 2016.08-2017.07 | 2016.07-2016.09 | 2018.03-2018.05 | 2012.03-2012.06 | 2017.01-2017.07 |\n| Number of riding records |   49,100,694    |   13,130,969    |   13,763,675    |    5,922,961    |    8,439,537    |   409,277,117   |   333,149,034   |    1,272,961    |     34,272      |     52,128      |\n| Number of stations       |       820       |       585       |       532       |       256       |       256       |       113       |       288       |       629       |       207       |       325       |\n\nFollowing shows the map-visualization of stations in NYC, Chicago, DC, Xian and Chengdu.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_NYC.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_Chicago.jpg\" style=\"zoom:23%;height:800px;width:800px;\"/> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Bike_DC.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/DiDi_Xian.jpg\" style=\"zoom:23%;height:800px;width:800px;\" />  <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/DiDi_Chengdu.jpg\" style=\"zoom:23%;height:800px;width:800px;\" />\n\n\n\nFollowing shows the map-visualization of stations in Chongqing, Shanghai and Beijing, METR-LA and PEMS-BAY.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Metro_Chongqing.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Metro_Shanghai.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/EV_Beijing.jpg\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/METR_LA.png\" style=\"zoom:23%;height:800px;width:800px;\" /> <img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/PEMS_BAY.png\" style=\"zoom:23%;height:800px;width:800px;\" />  \n\n## Results\n\nWe conducted experiments on the following datasets at the granularity of 15 minutes, 30 minutes, and 60 minutes respectively. More details and conclusions can be found in the this paper.  [IEEE Xplore](https://ieeexplore.ieee.org/document/9627543), [arXiv](https://arxiv.org/abs/2009.09379)\n\n### 15-minute prediction tasks\n\nThe best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction\n\n|                          |    NYC     |  Chicago   |     DC     |   Xi'an    |  Chengdu   |  Shanghai  | Chongqing  |  METR-LA   |  PEMS-BAY  |\n| :----------------------- | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: |\n| HM (TC)                  |   1.903    |   1.756    |   1.655    |   3.155    |   4.050    |   93.81    |   76.67    |   7.150    |   2.967    |\n| ARIMA (TC)               |   1.874    |   1.784    |   1.689    |   3.088    |   3.948    |   83.54    |   67.11    |   7.028    |   2.869    |\n| LSTM  (TC)               |   1.989    |   1.802    |   1.678    |   3.051    |   3.888    |   80.40    |   55.37    |   6.380    |   2.690    |\n| HM (TM)                  |   1.892    |   1.668    |   1.555    |   2.828    |   3.347    |   49.75    |   45.26    |   8.934    |   3.690    |\n| XGBoost (TM)             |   1.712    |   1.672    |   1.559    |   2.799    |   3.430    |   47.89    |   35.70    |   6.443    |   2.623    |\n| GBRT (TM)                |   1.708    |   1.667    |   1.552    |   2.775    |   3.363    |   44.55    |   33.29    |   6.371    |   2.645    |\n| TMeta-LSTM-GAL (TM)      |   1.818    |   1.623    |   1.540    |   2.917    |   3.286    |   45.88    |   33.34    |   6.156    |   2.544    |\n| DCRNN (TC+SP)            |   1.712    |   1.718    |   1.594    |   2.889    |   3.743    |   56.00    |   37.07    |   6.440    |   5.322    |\n| STGCN (TC+SP)            |   1.738    |   1.806    |   1.630    |   2.789    |   3.453    |   47.40    |   35.19    |   6.236    |   2.493    |\n| GMAN (TC+SP)             | **1.632*** | **1.529**  | **1.355*** |   2.769    |   3.520    |   49.21    |   36.66    |   6.214    |   3.484    |\n| Graph-WaveNet (TC+SP+SD) | **1.644**  | **1.460*** | **1.357**  |   2.764    |   3.442    |   47.84    |   35.04    | **5.270*** |   2.780    |\n| ST-ResNet (TM+SP)        |    ---     |    ---     |    ---     |   2.686    |   3.314    |    ---     |    ---     |    ---     |    ---     |\n| ST-MGCN (TM+SM)          |   1.687    |   1.646    |   1.545    |   2.714    |   3.293    |   46.54    | **32.72**  |   6.645    | **2.426*** |\n| AGCRN-CDW (TM+SD)        |   1.836    |   1.883    |   1.745    |   2.722    |   3.296    |   77.06    |   46.95    |   6.709    |   2.453    |\n| STMeta-GCL-GAL (TM+SM)   |   1.659    |   1.607    |   1.527    |   2.653    | **3.244**  | **41.67**  | **31.39*** | **5.644**  | **2.433**  |\n| STMeta-GCL-CON (TM+SM)   |   1.673    |   1.629    |   1.512    | **2.637*** | **3.241*** |   43.83    |   38.21    |   5.800    |   2.449    |\n| STMeta-DCG-GAL (TM+SM)   |   1.654    |   1.609    |   1.517    | **2.648**  |   3.254    | **40.94*** |   36.90    |   5.788    |   2.446    |\n\n### Results on 30-minute prediction tasks\n\nThe best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction\n\n|                          |    NYC     |  Chicago   |     DC     |   Xi'an    |  Chengdu   |  Shanghai  | Chongqing  |  Beijing   |  METR-LA   |  PEMS-BAY  |\n| :----------------------- | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: |\n| HM (TC)                  |   3.206    |   2.458    |   2.304    |   5.280    |   6.969    |   269.16   |   221.39   |   0.768    |   9.471    |   4.155    |\n| ARIMA (TC)               |   3.178    |   2.428    |   2.228    |   5.035    |   6.618    |   212.01   |   180.53   |   0.755    |   9.230    |   3.936    |\n| LSTM  (TC)               |   3.018    |   2.493    |   2.212    |   4.950    |   6.444    |   195.60   |   104.61   |   0.755    |   7.866    |   3.683    |\n| HM (TM)                  |   2.686    |   2.230    |   1.956    |   4.239    |   4.851    |   108.59   |   74.55    |   0.864    |   9.560    |   3.965    |\n| XGBoost (TM)             |   2.704    |   2.376    |   1.956    |   4.172    |   4.915    |   81.82    |   69.50    |   0.686    |   8.298    |   3.253    |\n| GBRT (TM)                |   2.682    |   2.355    |   1.928    |   4.135    |   4.873    |   83.94    |   72.99    |   0.689    |   8.269    |   3.370    |\n| TMeta-LSTM-GAL (TM)      |   2.511    | **2.133*** |   1.927    |   3.847    |   4.678    |   85.19    |   53.18    |   0.686    |   7.436    |   3.231    |\n| DCRNN (TC+SP)            |   2.618    |   2.246    |   2.118    |   4.529    |   6.258    |   116.15   |   65.72    |   0.757    |   8.562    |   6.198    |\n| STGCN (TC+SP)            |   2.841    |   2.482    |   2.067    |   3.992    |   5.051    |   91.29    |   58.34    |   0.694    |   7.871    |   3.136    |\n| GMAN (TC+SP)             |   2.792    |   2.336    | **1.836*** |   4.026    |   5.293    |   97.58    |   51.37    |   0.764    |   7.276    |   3.688    |\n| Graph-WaveNet (TC+SP+SD) |   2.666    |   2.158    |   1.874    |   3.986    |   5.097    |   92.88    |   52.52    |   0.719    | **6.809*** |   3.589    |\n| ST-ResNet (TM+SP)        |    ---     |    ---     |    ---     |   3.903    |   4.673    |    ---     |    ---     |    ---     |    ---     |    ---     |\n| ST-MGCN (TM+SM)          |   2.513    |   2.177    |   1.903    |   3.886    |   4.732    |   88.76    |   50.96    |   0.691    |   8.079    | **3.042**  |\n| AGCRN-CDW (TM+SD)        |   2.830    |   2.565    |   2.074    |   3.958    |   4.753    |   238.99   |   131.55   |   0.688    |   8.575    | **3.022*** |\n| STMeta-GCL-GAL (TM+SM)   | **2.410*** |   2.170    |   1.856    | **3.808**  |   4.650    | **75.36*** | **49.47**  | **0.670**  |   7.156    |   3.116    |\n| STMeta-GCL-CON (TM+SM)   | **2.411**  | **2.133*** |   1.859    | **3.772*** | **4.613*** |   80.69    |   50.01    | **0.667*** | **6.889*** |   3.204    |\n| STMeta-DCG-GAL (TM+SM)   | **2.411**  |   2.182    | **1.852**  |   3.833    | **4.635**  | **77.49**  | **48.96*** | **0.670**  |   7.184    |   3.187    |\n\n### Results on 60-minute prediction tasks\n\nThe best two results are highlighted in bold, and the top one result is marked with `*'. (TC: Temporal Closeness; TM: Multi-Temporal Factors; SP: Spatial Proximity; SM: Multi-Spatial Factors; SD: Data-driven Spatial Knowledge Extraction\n\n|                          |    NYC     |  Chicago   |     DC     |   Xi'an    |  Chengdu   |  Shanghai   | Chongqing  |  Beijing   |  METR-LA   |  PEMS-BAY  |\n| :----------------------- | :--------: | :--------: | :--------: | :--------: | :--------: | :---------: | :--------: | :--------: | :--------: | :--------: |\n| HM (TC)                  |   5.814    |   4.143    |   3.485    |   10.136   |   14.145   |   824.94    |   673.55   |   1.178    |   12.303   |   5.779    |\n| ARIMA (TC)               |   5.289    |   3.744    |   3.183    |   9.475    |   13.259   |   676.79    |   578.19   |   0.982    |   11.739   |   5.670    |\n| LSTM  (TC)               |   5.167    |   3.721    |   3.234    |   9.830    |   13.483   |   506.07    |   322.81   |   0.999    |   10.083   |   4.777    |\n| HM (TM)                  |   3.992    |   3.104    |   2.632    |   6.186    |   7.512    |   172.55    |   119.86   |   1.016    |   10.727   |   4.018    |\n| XGBoost (TM)             |   4.102    |   3.003    |   2.643    |   6.733    |   7.592    |   160.38    |   117.05   |   0.834    |   10.299   |   3.703    |\n| GBRT (TM)                |   4.039    |   2.984    |   2.611    |   6.446    |   7.511    |   154.29    |   113.92   |   0.828    |   10.013   |   3.704    |\n| TMeta-LSTM-GAL (TM)      |   3.739    |   2.840    |   2.557    | **5.843**  |   6.949    |   163.31    |   102.86   |   0.840    | **8.670*** |   3.616    |\n| DCRNN (TC+SP)            |   4.187    |   3.081    |   3.016    |   8.203    |   11.444   |   340.25    |   122.31   |   0.989    |   11.121   |   6.920    |\n| STGCN (TC+SP)            |   3.895    |   2.989    |   2.597    |   6.150    |   7.710    |   187.98    |   106.16   |   0.859    |   10.688   |   3.472    |\n| GMAN (TC+SP)             |   4.251    |   2.875    |   2.530    |   7.099    |   13.351   |   193.39    |   117.52   |   0.949    |   10.012   |   3.846    |\n| Graph-WaveNet (TC+SP+SD) |   3.863    |   2.812    | **2.403*** |   6.541    |   8.162    |   186.82    |   102.75   |   0.930    |   9.463    |   4.135    |\n| ST-ResNet (TM+SP)        |    ---     |    ---     |    ---     |   6.075    |   7.155    |     ---     |    ---     |    ---     |    ---     |    ---     |\n| ST-MGCN (TM+SM)          |   3.723    |   2.904    |   2.518    |   5.878    |   7.067    |   159.52    |   104.87   |   0.827    |   10.798   | **3.486**  |\n| AGCRN-CDW (TM+SD)        |   3.795    |   2.935    |   2.580    |   8.835    |   10.275   |   658.12    |   287.41   |   0.844    |   10.728   | **3.381*** |\n| STMeta-GCL-GAL (TM+SM)   | **3.518**  | **2.695**  |   2.405    |   5.871    | **6.858*** |   153.17    | **97.87**  |   0.831    | **8.834**  |   3.514    |\n| STMeta-GCL-CON (TM+SM)   | **3.507*** |   2.739    | **2.404**  | **5.829*** | **6.873**  | **149.05**  |   106.41   | **0.807**  |   9.147    |   3.552    |\n| STMeta-DCG-GAL (TM+SM)   |   3.521    | **2.652*** |   2.423    |   5.908    |   6.904    | **143.18*** | **94.78*** | **0.803*** |   8.993    |   3.500    |\n\n## Implement Details\n\n### Search Space\n\nWe use [nni](https://github.com/microsoft/nni) toolkit to search the best parameters of HM, XGBoost and GBRT model. Search space are following.\n\n|  Model  |                         Search Space                         |\n| :-----: | :----------------------------------------------------------: |\n|   HM    |               `CT: 0~6`, `PT: 0~7`, `TT: 0~4`                |\n|  ARIMA  |                ``CT:168``,`p:3`, `d:0`, `q:0`                |\n| XGBoost | `CT: 0~12`, `PT: 0~14`, `TT: 0~4`, `estimater: 10~200`, `depth: 2~10` |\n|  GBRT   | `CT: 0~12`, `PT: 0~14`, `TT: 0~4`, `estimater: 10~200`, `depth: 2~10` |\n\n### Bike-sharing\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |      NYC       |    Chicago     |       DC       |\n  | :--------: | :------------: | :------------: | :------------: |\n  |     HM     |    `3-1-2`     |    `5-0-4`     |    `3-7-4`     |\n  |  XGBoost   | `8-14-4-32-2`  | `11-13-4-28-2` | `4-14-4-27-2`  |\n  |    GBRT    | `7-13-4-144-1` | `7-15-4-101-2` | `8-11-5-101-2` |\n\n  | 30 minutes |      NYC       |    Chicago    |       DC        |\n  | :--------: | :------------: | :-----------: | :-------------: |\n  |     HM     |    `2-1-2`     |    `3-2-1`    |     `3-1-4`     |\n  |  XGBoost   | `12-8-1-36-3`  | `7-5-2-24-2`  | `12-13-4-27-2`  |\n  |    GBRT    | `12-10-0-72-4` | `9-13-2-91-2` | `13-15-5-140-1` |\n\n  | 60 minutes |      NYC       |    Chicago    |      DC       |\n  | :--------: | :------------: | :-----------: | :-----------: |\n  |     HM     |    `1-1-3`     |    `1-1-1`    |    `2-1-3`    |\n  |  XGBoost   | `13-7-0-103-3` | `11-8-0-35-4` | `11-9-5-28-3` |\n  |    GBRT    | `12-6-1-58-5`  | `11-8-1-92-5` | `11-8-5-54-3` |\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/bike_trial.py) Run Code & Setting.\n\n* [DCRNN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/bike_trial.py) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on  [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [bike_nyc.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_nyc.data.yml) , [bike_chicago.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_chicago.data.yml), [bike_dc.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/bike_dc.data.yml)\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n            ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n            ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n            ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n            ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n            ' -p data_range:0.25,train_data_length:91,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n            ' -p data_range:0.5,train_data_length:183,graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n  ```\n\n  * TMeta-LSTM-GAL\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_nyc.data.yml -p graph:Distance,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_chicago.data.yml -p graph:Distance,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.25,train_data_length:91,graph:Distance,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p data_range:0.5,train_data_length:183,graph:Distance,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d bike_dc.data.yml -p graph:Distance,MergeIndex:12')\n  ```\n\n  * STMeta-V1\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_nyc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_chicago.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d bike_dc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  ```\n\n  * STMeta-V2\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_nyc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_chicago.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d bike_dc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  ```\n\n  * STMeta-V3\n\n  ```python\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_nyc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_chicago.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  \n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.25,train_data_length:91,graph:Distance-Correlation-Interaction,MergeIndex:3')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n            '-p data_range:0.5,train_data_length:183,graph:Distance-Correlation-Interaction,MergeIndex:6')\n  os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d bike_dc.data.yml '\n            '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n  ```\n\n### Ride-sharing\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |   **Xi'an**   |  **Chengdu**   |\n  | :--------: | :-----------: | :------------: |\n  |     HM     |    `5-0-4`    |    `2-7-4`     |\n  |  XGBoost   | `7-14-0-10-4` | `12-14-1-27-3` |\n  |    GBRT    | `11-2-2-45-3` | `13-15-5-39-3` |\n\n  | 30 minutes |  **Xi'an**   |  **Chengdu**   |\n  | :--------: | :----------: | :------------: |\n  |     HM     |   `2-0-2`    |    `1-7-4`     |\n  |  XGBoost   | `9-0-2-25-3` | `9-14-3-16-3`  |\n  |    GBRT    | `9-0-2-80-3` | `10-10-5-34-3` |\n\n  | 60 minutes |   **Xi'an**   |  **Chengdu**  |\n  | :--------: | :-----------: | :-----------: |\n  |     HM     |    `1-1-2`    |    `0-7-4`    |\n  |  XGBoost   | `12-0-2-10-5` | `9-6-2-14-3`  |\n  |    GBRT    | `9-0-2-50-2`  | `9-12-2-50-5` |\n\n* ST-ResNet\n\n  |                    ST-ResNet Search Space                    |\n  | :----------------------------------------------------------: |\n  | ``residual_units:2~6``,  `conv_filter:[32, 64, 128]`,  `kernal_size:3~5`, <br />`lr:[0.0001, 0.00002, 0.00004, 0.00008, 0.00001]`, `batch_size:[32, 64, 128, 256]` |\n\n  The best parameters found are following.\n\n  ```python\n  args = {\n    'dataset': 'DiDi',\n    'city': 'Chengdu',\n    'num_residual_unit': 4,\n    'conv_filters': 64,\n    'kernel_size': 3,\n    'lr': 1e-5,\n    'batch_size': 32\n  \n  ```\n\n  We can modify `city` parameter to `Chengdu` or `Xian` in [ST_ResNet.py]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_ResNet/ST_ResNet.py ) , and then run it.\n\n  ```bash\n   python ST_ResNet.py \n  ```\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/didi_trial.py) Run Code & Setting.\n\n* [DCRNN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/didi_trial.py ) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [didi_xian.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_xian.data.yml) , [didi_chengdu.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/didi_chengdu.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml'\n            ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    ```\n  \n  * TMeta-LSTM-GAL\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_xian.data.yml -p graph:Distance,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d didi_chengdu.data.yml -p graph:Distance,MergeIndex:12')\n    ```\n  \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    ```\n    \n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    ```\n  \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_xian.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d didi_chengdu.data.yml '\n              '-p graph:Distance-Correlation-Interaction,MergeIndex:12')\n    ```\n    \n\n### Metro Passenger\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |  **Chongqing**  |  **Shanghai**  |\n  | :--------: | :-------------: | :------------: |\n  |     HM     |     `2-1-4`     |    `1-0-4`     |\n  |  XGBoost   |  `12-6-4-51-8`  | `11-10-4-31-7` |\n  |    GBRT    | `12-14-1-182-7` | `12-7-1-148-5` |\n\n  | 30 minutes | **Chongqing**  |  **Shanghai**  |\n  | :--------: | :------------: | :------------: |\n  |     HM     |    `1-0-4`     |    `1-1-3`     |\n  |  XGBoost   | `11-5-0-45-8`  | `12-6-1-206-3` |\n  |    GBRT    | `10-3-0-107-8` |  `7-4-1-58-7`  |\n\n  | 60 minutes |  **Chongqing**   | **Shanghai** |\n  | :--------: | :--------------: | :----------: |\n  |     HM     |     `0-1-4`      |   `0-0-4`    |\n  |  XGBoost   |  `9-14-2-200-5`  | `3-7-0-50-5` |\n  |    GBRT    | `12-10-4-200-5 ` | `9-5-1-66-6` |\n\n* [ST_MGCN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metro_trial.py ) Run Code & Setting.\n\n* [DCRNN](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metro_trial.py) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [metro_chongqing.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_chongqing.data.yml) , [metro_shanghai.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metro_shanghai.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM \n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    ```\n    \n  * TMeta-LSTM-GAL\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_chongqing.data.yml -p graph:Distance,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metro_shanghai.data.yml -p graph:Distance,MergeIndex:12')\n    ```\n  \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    ```\n  \n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    ```\n    \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_chongqing.data.yml '\n            '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml -d metro_shanghai.data.yml '\n              '-p graph:Distance-Correlation-Line,MergeIndex:12')\n    ```\n    \n\n### Electric Vehicle\n\n* HM & XGBoost & GBRT\n\n  | Beijing |  30 minutes   |   60 minutes    |\n  | :-----: | :-----------: | :-------------: |\n  |   HM    |    `2-0-0`    |     `2-0-2`     |\n  | XGBoost | `6-6-1-19-2`  |  `12-7-0-20-2`  |\n  |  GBRT   | `13-3-2-47-3` | `12-10-0-100-2` |\n\n* [ST_MGCN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/cs_trial.py ) Run Code & Setting.\n\n* [DCRNN]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/cs_trial.py ) Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [chargestation_beijing.data.yml]( https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/chargestation_beijing.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM \n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d chargestation_beijing.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:2')\n    ```\n  \n  * TMeta-LSTM-GAL\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance,MergeIndex:2')\n    ```\n  \n  * STMeta-V1\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n            ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n    ```\n  * STMeta-V2\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n            ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n    ```\n  \n  * STMeta-V3\n  \n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:1')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d chargestation_beijing.data.yml -p graph:Distance-Correlation,MergeIndex:2')\n    ```\n\n### Traffic Speed\n\n* HM & XGBoost & GBRT\n\n  | 15 minutes |  **METR-LA**  | **PEMS-BAY**  |\n  | :--------: | :-----------: | :-----------: |\n  |     HM     |    `2-0-4`    |    `1-0-1`    |\n  |  XGBoost   | `11-1-2-25-3` | `12-4-2-21-4` |\n  |    GBRT    | `11-8-2-29-4` | `10-6-1-65-6` |\n\n  | 30 minutes |  **METR-LA**  |  **PEMS-BAY**  |\n  | :--------: | :-----------: | :------------: |\n  |     HM     |    `2-0-4`    |    `1-0-1`     |\n  |  XGBoost   | `6-6-0-25-3`  | `12-13-2-27-3` |\n  |    GBRT    | `10-0-0-27-3` | `12-6-2-90-7`  |\n\n  | 60 minutes |  **METR-LA**  | **PEMS-BAY**  |\n  | :--------: | :-----------: | :-----------: |\n  |     HM     |    `2-1-4`    |    `1-1-4`    |\n  |  XGBoost   | `2-2-0-25-3`  | `12-6-2-19-3` |\n  |    GBRT    | `4-5-1-19-4`  | `12-7-2-59-5` |\n\n* [METR-LA](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/metr_trial.py)  and [PEMS-BAY](https://github.com/Di-Chai/UCTB/blob/master/Experiments/ST_MGCN/pems_trial.py)  ST_MGCN Run Code & Setting.\n\n* [METR-LA](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/metr_trial.py) and [PEMS-BAY](https://github.com/Di-Chai/UCTB/blob/master/Experiments/DCRNN/pems_trial.py) DCRNN Run Code & Setting.\n\n* LSTM & TMeta-LSTM-GAL & STMeta-V1  & STMeta-V2  & STMeta-V3\n\n  These five models can be run by specifying data files and model files on [STMeta_Obj.py](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_Obj.py).\n\n  Data Files: [metr_la.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/metr_la.data.yml) , [pems_bay.data.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/pems_bay.data.yml).\n\n  Model Files: [STMeta_v0.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v0.model.yml), [STMeta_v1.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v1.model.yml).,  [STMeta_v2.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v2.model.yml)., [STMeta_v3.model.yml](https://github.com/Di-Chai/UCTB/blob/master/Experiments/STMeta/STMeta_v3.model.yml).\n\n  * LSTM \n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d metr_la.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml -d pems_bay.data.yml'\n              ' -p graph:Distance,period_len:0,trend_len:0,mark:LSTMC,MergeIndex:12')\n    ```\n\n  * TMeta-LSTM-GAL\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v0.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance,MergeIndex:12')\n    ```\n\n  * STMeta-V1\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v1.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    ```\n\n  * STMeta-V2\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v2.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    ```\n\n  * STMeta-V3\n\n    ```python\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d metr_la.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    \n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:3')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:6')\n    os.system('python STMeta_Obj.py -m STMeta_v3.model.yml'\n              ' -d pems_bay.data.yml -p graph:Distance-Correlation,MergeIndex:12')\n    ```\n\n"
  },
  {
    "path": "docs/sphinx/md_file/installation.md",
    "content": "## Installation\n\nUCTB is based on several well-known deep learning frameworks, including **PyTorch**, **TensorFlow**, and **MXNet**. If you have an Nvidia GPU installed on your computer, we highly recommend you install the GPU version of these frameworks.\n\nUCTB toolbox may not work successfully with the upgrade of some packages. We thus encourage you to use the specific version of packages to avoid unseen errors. ***To avoid potential conflict, we highly recommend you install UCTB vis Anaconda.***\n\n### Install via Anaconda\n\n**Step 1: Install Anaconda**\n\nYou can skip to step 2 if you already installed Anaconda.\n\nTo install Anaconda, please refer to this page <https://www.anaconda.com/download>.\n\n\n\n**Step 2: create UCTB environment**\n\nCreate the UCTB environment by the following command. You may need the [environment.yaml](https://github.com/uctb/UCTB/blob/master/environment.yaml) file.\n\n```bash\nconda env create -f environment.yaml\n```\n\nThen activate the UCTB environment and start to use it. 🎉🎉🎉\n\n```bash\nconda activate UCTB\n```\n\n\n\n### Check for Success\n\nIf you  successfully install UCTB, you may get the following output after importing UCTB. \n\n```\n(UCTB) XXX:~$ python\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n>>> import UCTB\nUsing TensorFlow backend.\n>>> \n```\n\n### High version GPU Framework support\n\n**Existing Problems**\n\nDue to changes in the design architecture of high-version GPUs, low-version CUDA is not compatible with high-version GPUs. As a result, Tensorflow 1.x is only compatible with low-version CUDA, leading to runtime failures on machines equipped with high-version GPUs. https://stackoverflow.com/questions/50622525/which-tensorflow-and-cuda-version-combinations-are-compatible \n\n**Solution**\n\nThanks to the [Nvidia TensorFlow](https://github.com/NVIDIA/tensorflow) project, which was created to support newer hardware and improve libraries for NVIDIA GPU users using TensorFlow 1.x, we can now install UCTB on machines with newer GPUs. You can follow the installation tutorial below to start enjoying UCTB.\n\n**Clone the project**\n\n```sh\n>>> git clone git@github.com:uctb/UCTB.git\n>>> cd UCTB\n```\n\n**Create Anaconda Environment**\n\n```sh\n>>> conda create -n UCTB python=3.8\n>>> conda activate UCTB\n```\n\n**Install Nvidia Tensorflow**\n\n```sh\n>>> pip install --user nvidia-pyindex\n>>> pip install --user nvidia-tensorflow[horovod]\n```\n\n**Install UCTB from Source**\n\n```sh\n>>> python build_install.py\n```\n\n\n\n### Q & A\n\n**Q: I fail to install PyTorch, TensorFlow, and MXNet, what is the version number of them?**\n\nA: We recommend you install PyTorch==1.1.0, TensorFlow==1.13.1, and MXNet==1.5.0 with cuda version 10.0. We here give the installation command:\n\n```bash\n# Install PyTorch\nconda install pytorch==1.1.0 torchvision==0.3.0 cudatoolkit=10.0 -c pytorch\n\n# Install TensorFlow\nconda install tensorflow-gpu==1.13.1\n\n# Install MXNet\npip install mxnet-cu100==1.5.0\n```\n\n\n\n**Q:  I'm using Windows OS, and my Anaconda reports that it cannot find the PyTorch 1.1.0 packages. How to install it?**\n\nA: You could install it by the following command.\n\n```bash\npip install torch==1.1.0 torchvision==0.3.0 -f https://download.pytorch.org/whl/cu100/torch_stable.html\n```\n\n\n\n**Q:  I fail to install UCTB via pip. How to install it ?**\n\nA: This situation may occur when your OS is Windows. You could install UCTB by its source code. First download UCTB's source code and your folder may look like this:\n\n```bash\nXXX/UCTB-master# ls\nbuild_install.py  dist  environment.yaml  __init__.py  QuickStarts  setup.py\nbuild.py          docs  Experiments       LICENSE      README.md    UCTB\n```\n\nthen build and install UCTB by the following command:\n\n```bash\npython build_install.py\n```\n\n<u>[Back To HomePage](../index.html)</u>"
  },
  {
    "path": "docs/sphinx/md_file/introduction.md",
    "content": "## Introduction\n\n**Urban Computing Tool Box** is a package providing [**urban datasets**](https://github.com/uctb/Urban-Dataset), [**spatial-temporal prediction models**](https://github.com/uctb/UCTB), and [**visualization tools**](https://github.com/uctb/visualization-tool-UCTB) for various urban computing tasks, such as traffic prediction, crowd flow prediction, ridesharing demand prediction, etc. \n\nUCTB is a flexible and open package. You can use the data we provided or use your data, and the data structure is well stated in the [**tutorial section**](https://uctb.github.io/UCTB/md_file/tutorial.html). \n\n### Urban Datasts\n\nUCTB also releases [a public dataset repository](https://github.com/uctb/Urban-Dataset) including the following applications:\n\n| **Application**  |        **City**        |     **Time Range**     | **Temporal Granularity** |                                                      **Dataset Link**                                                       |\n|:----------------:|:----------------------:|:----------------------:|:------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|\n|   Bike-sharing   |          NYC           | 2013.07.01-2017.09.30  |        5 minutes         |            [66.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip)             | \n|   Bike-sharing   |        Chicago         | 2013.07.01-2017.09.30  |        5 minutes         |          [30.2M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip)           | \n|   Bike-sharing   |           DC           | 2013.07.01-2017.09.30  |        5 minutes         |             [31.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip)             | \n| Pedestrian Count |       Melbourne        | 2021.01.01-2022.11.01  |        60 minutes        | [1.18M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip) |\n|  Vehicle Speed   |           LA           | 2012.03.01-2012.06.28  |        5 minutes         |            [11.8M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip)             |\n|  Vehicle Speed   |          BAY           | 2017.01.01-2017.07.01  |        5 minutes         |            [27.9M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip)            |\n|   Taxi Demand    |        Chicago         | 2013.01.01-2018.01.01  |        15 minutes        |          [6.1M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|       Bus        |          NYC           | 2022.02.01-2024.01.13  |         60 mins          |             [4.89M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip)             |\n|      Metro       |          NYC           | 2022.02.01-2023.12.21  |         60 mins          |           [11.3M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip)           |\n|   Traffic Flow   |         Luzern         | 2015.01.01-2016.01.01  |          3 mins          |            [21M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Flow/3_minutes/Flow_Luzern.zip)            |\n|   Ride-sharing   |  Chicago (community)   | 2013.01.01-2018.01.01  |         15 mins          |          [6.06](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|   Ride-sharing   | Chicago (census tract) | 2013.01.01-2018.01.01  |         15 mins          |    [10M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip)     |\n|   Ride-sharing   |          NYC           | 2009.01.01-2023.06.01  |          5 mins          |    \n\nWe provide [detailed documents](https://github.com/uctb/Urban-Dataset/blob/main/Tutorial/tutorial.ipynb) about how to build and how to use these datasets.\n\n### Predictive Tool\n\nCurrently, the package supports the following models: (This toolbox is constructed based on some open-source repos. We appreciate these awesome implements. [See more details](https://uctb.github.io/UCTB/md_file/static/current_supported_models.html)).\n\n| Model Name                                                   | Input Data Format | Spatial Modeling Technique | Graph Type                                                   | Temporal Modeling Technique | Temporal Knowledge     | Module                      |\n| ------------------------------------------------------------ | ----------------- | -------------------------- | ------------------------------------------------------------ | --------------------------- | ---------------------- | --------------------------- |\n| ARIMA                                                        | Both              | N/A                        | N/A                                                          | SARIMA                      | Closeness              | ``UCTB.model.ARIMA``        |\n| HM                                                           | Both              | N/A                        | N/A                                                          | N/A                         | Closeness              | ``UCTB.model.HM``           |\n| HMM                                                          | Both              | N/A                        | N/A                                                          | HMM                         | Closeness              | ``UCTB.model.HMM``          |\n| XGBoost                                                      | Both              | N/A                        | N/A                                                          | XGBoost                     | Closeness              | ``UCTB.model.XGBoost``      |\n| DeepST [[SIGSPATIAL 2016]](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf) | Grid              | CNN                        | N/A                                                          | CNN                         | Closeness,Period,Trend | ``UCTB.model.DeepST``       |\n| ST-ResNet [[AAAI 2017]](https://arxiv.org/pdf/1610.00081.pdf) | Grid              | CNN                        | N/A                                                          | CNN                         | Closeness,Period,Trend | ``UCTB.model.ST_ResNet``    |\n| DCRNN  [[ICLR 2018]](https://arxiv.org/pdf/1707.01926.pdf)   | Node              | GNN                        | **Prior**(Sensor Network)                                    | RNN                         | Closeness              | ``UCTB.model.DCRNN``        |\n| GeoMAN  [[IJCAI 2018]](https://www.ijcai.org/proceedings/2018/0476.pdf) | Node              | Attention                  | **Prior**(Sensor Networks)                                   | Attention+LSTM              | Closeness              | ``UCTB.model.GeoMAN``       |\n| STGCN  [[IJCAI 2018]](https://www.ijcai.org/proceedings/2018/0505.pdf) | Node              | GNN                        | **Prior**(Traffic Network)                                   | Gated CNN                   | Closeness              | ``UCTB.model.STGCN``        |\n| GraphWaveNet [[IJCAI 2019]](https://www.ijcai.org/proceedings/2019/0264.pdf) | Node              | GNN                        | **Adaptive**                                                 | TCN                         | Closeness              | ``UCTB.model.GraphWaveNet`` |\n| ASTGCN  [[AAAI 2019]](https://ojs.aaai.org/index.php/AAAI/article/view/3881) | Node              | GNN+Attention              | **Prior**(Traffic Network)                                   | Attention                   | Closeness,Period,Trend | ``UCTB.model.ASTGCN``       |\n| ST-MGCN   [[AAAI 2019]](https://ojs.aaai.org/index.php/AAAI/article/view/4247) | Node              | GNN                        | **Prior**(Neighborhood,Functional similarity,Transportation connectivity) | CGRNN                       | Closeness              | ``UCTB.model.ST_MGCN``      |\n| GMAN  [[AAAI 2020]](https://ojs.aaai.org/index.php/AAAI/article/view/5477/5333) | Node              | Attention                  | **Prior**(Road Network)                                      | Attention                   | Closeness              | ``UCTB.model.GMAN``         |\n| STSGCN  [[AAAI 2020]](https://ojs.aaai.org/index.php/AAAI/article/view/5438) | Node              | GNN+Attention              | **Prior**(Spatial Network)                                   | Attention                   | Closeness              | ``UCTB.model.STSGCN``       |\n| AGCRN [[NeurIPS 2020]](https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf) | Node              | GNN                        | **Adaptive**                                                 | RNN                         | Closeness              | ``UCTB.model.AGCRN``        |\n| STMeta [[TKDE 2021]](https://arxiv.org/abs/2009.09379)       | Node              | GNN                        | **Prior**(Proximity,Functionality,Interaction/Same-line)     | LSTM/RNN                    | Closeness,Period,Trend | ``UCTB.model.STMeta``       |\n\n### Visualization Tool\n\nThe Visualization tool integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis.\n\nWelcome to visit the [website](http://39.107.116.221/) for a trial! \n\n<u>[Back To HomePage](../index.html)</u>\n"
  },
  {
    "path": "docs/sphinx/md_file/predictive_tool.md",
    "content": "# Predictive Tool\n\n## Currently Supported Models\n\n### AGCRN\n\nAGCRN (Adaptive Graph Convolutional Recurrent Network) is a deep nerual network for traffic prediction consisting of two adaptive module and recurrent networks.\n\n- Reference Paper:\n  - [Bai, L., Yao, L., Li, C., Wang, X., & Wang, C. (2020). Adaptive graph convolutional recurrent network for traffic forecasting.](https://proceedings.neurips.cc/paper/2020/file/ce1aad92b939420fc17005e5461e6f48-Paper.pdf)\n- Reference Implementation:\n  - [Github repository (LeiBAI)](https://github.com/LeiBAI/AGCRN)\n\n###  ARIMA\n\nARIMA (Autoregressive Integrated Moving Average) is a widely used classical statistical model on time series prediction.\n\n- Reference Paper:\n\n  + [Williams, B. M., & Hoel, L. A. (2003). Modeling and forecasting vehicular traffic flow as a seasonal ARIMA process: Theoretical basis and empirical results](https://www3.nd.edu/~busiforc/handouts/ARIMA%20Engineering%20Article.pdf)\n- Reference Package: `pandas`, `statsmodels`\n\n### ASTGCN \n\nASTGCN (Attenion Based Spatial-temporal Graph Convolutional Networks) is a deep neural network for traffic flow forecasting. It models temporal-dependencies from three perspectives using attetion mechanism. And it models spatial-dependencies employing graph convolutions.\n\n- Reference Paper:\n  - [Guo, S., Lin, Y., Feng, N., Song, C., & Wan, H. (2019, July). Attention based spatial-temporal graph convolutional networks for traffic flow forecasting.](https://ojs.aaai.org/index.php/AAAI/article/view/3881)\n- Reference Implementation:\n  - [Github repository (guoshnBJTU)](https://github.com/guoshnBJTU/ASTGCN-r-pytorch)\n\n###  DCRNN\n\nDCRNN (Diffusion Convolutional Recurrent Neural Network) is a deep learning framework for traffic forecasting that incorporates both spatial and temporal dependency in the traffic flow. It captures the spatial dependency using bidirectional random walks on the graph, and the temporal dependency using the encoder-decoder architecture with scheduled sampling.\n\n- Reference Paper:\n\n  + [Li, Y., Yu, R., Shahabi, C., & Liu, Y. (2017). Diffusion convolutional recurrent neural network: Data-driven traffic forecasting](https://arxiv.org/abs/1707.01926)\n- Reference Implementation: \n  + [A TensorFlow implementation of Diffusion Convolutional Recurrent Neural Network (liyaguang)](https://github.com/liyaguang/DCRNN)\n\n###  DeepST\n\nDeepST (Deep learning-based prediction model for Spatial-Temporal data) is composed of three components: 1) temporal dependent instances: describing temporal closeness, period and seasonal trend; 2) convolutional neural networks: capturing near and far spatial dependencies; 3) early and late fusions: fusing similar and different domains' data.\n\n- Reference Paper:\n\n  + [Zhang, J., Zheng, Y., Qi, D., Li, R., & Yi, X. (2016, October). DNN-based prediction model for spatio-temporal data](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/09/DeepST-SIGSPATIAL2016.pdf)\n\n###  GeoMAN \n\nGeoMAN (Multi-level Attention Networks for Geo-sensory Time Series Prediction) consists of two major parts: 1) A multi-level attention mechanism (including both local and global  spatial attentions in encoder and temporal attention in decoder) to model the dynamic spatio-temporal  dependencies; 2) A general fusion module to incorporate the external factors from different domains (e.g.,  meteorology, time of day and land use).\n\n- Reference Paper:\n\n  + [Liang, Y., Ke, S., Zhang, J., Yi, X., & Zheng, Y. (2018, July). GeoMAN: Multi-level Attention Networks for Geo-sensory Time Series Prediction](https://www.ijcai.org/proceedings/2018/0476.pdf)\n- Reference Implementation:\n  + [An easy implement of GeoMAN using TensorFlow (yoshall & CastleLiang)](https://github.com/yoshall/GeoMAN)\n\n### GMAN\n\nGMAN (Graph Multi-Attention Network) is a deep nerual network for traffic prediction adopting encoder-decoder architecture. Both encode and decoder consist of multiple spatio-temporal attention blocks to model spatio-temporal dependencies.\n\n- Reference Paper:\n  - [Zheng, C., Fan, X., Wang, C., & Qi, J. (2020, April). Gman: A graph multi-attention network for traffic prediction.](https://ojs.aaai.org/index.php/AAAI/article/view/5477)\n- Reference Implementation:\n  - [implementation of Graph Multi-Attention Network](https://github.com/zhengchuanpan/GMAN)\n\n### GraphWaveNet\n\nGraphWaveNet is an end-to-end novel graph neural network. It captures spatial dependencies through a self-adptive adjacency matrix. And it captures temporal dependencies through convolutions.\n\n- Reference Paper:\n  - [Wu, Z., Pan, S., Long, G., Jiang, J., & Zhang, C. (2019). Graph wavenet for deep spatial-temporal graph modeling.](https://www.ijcai.org/proceedings/2019/0264.pdf)\n- Reference Implementation:\n  - [Github repository (nnzhan)](https://github.com/nnzhan/Graph-WaveNet)\n\n###  HM (Historical Mean)\n\nHM is a constant model and always forecasts the sample mean of the historical data.\n\n###  HMM (Hidden Markov Model)\n\nHidden Markov Model is a statistical Markov model in which the system being modeled is assumed to be a Markov process with hidden states. It is often used in temporal pattern recognition.\n\n- Reference Paper:\n\n  + [Chen, Z., Wen, J., & Geng, Y. (2016, November). Predicting future traffic using hidden markov models](https://ieeexplore.ieee.org/abstract/document/7785328)\n- Reference Package: `hmmlearn`\n\n### STGCN \n\nSTGCN (Spatio-temporal Graph Convolutional Networks) is a deep learning framework for traffic forecasting with complete convolutional structures.\n\n- Reference Paper:\n  - [Yu, B., Yin, H., & Zhu, Z. (2017). Spatio-temporal graph convolutional networks: A deep learning framework for traffic forecasting.](https://www.ijcai.org/proceedings/2018/0505.pdf)\n- Reference Implementation:\n  - [Github repository (VeritasYin)](https://github.com/VeritasYin/STGCN_IJCAI-18)\n\n### STMeta\n\nSTMeta is our prediction model, which requires extra graph information as input, and combines Graph Convolution LSTM and Attention mechanism.\n\n- Reference Package: `tensorflow`\n\n### ST-MGCN \n\nST-MGCN (Spatiotemporal Multi-graph Convolution Network) is a deep learning based model which encoded the non-Euclidean correlations among regions using multiple graphs and explicitly captured them using multi-graph convolution.\n\n- Reference Paper:\n\n  + [Geng, X., Li, Y., Wang, L., Zhang, L., Yang, Q., Ye, J., & Liu, Y. (2019). Spatiotemporal multi-graph convolution network for ride-hailing demand forecasting](https://ieeexplore.ieee.org/abstract/document/7785328)\n- Reference Implementation:\n  + [A PyTorch implementation of the ST-MGCN model  (shawnwang-tech)](https://github.com/shawnwang-tech/ST-MGCN-pytorch)\n\n### ST-ResNet\n\nST-ResNet is a deep-learning model with an end-to-end structure based on unique properties of spatio-temporal data making use of convolution and residual units.\n\n- Reference Paper:\n  - [Zhang, J., Zheng, Y., & Qi, D. (2017, February). Deep spatio-temporal residual networks for citywide crowd flows prediction](https://arxiv.org/pdf/1610.00081.pdf)\n- Reference Implementation:\n  - [Github repository (lucktroy)](https://github.com/lucktroy/DeepST/tree/master/scripts/papers/AAAI17)\n\n### STSGCN \n\nSTSGCN (Spatial-temporal Synchronous Graph Convolutional Networks) is a deep learning framework for spatial-temporal network data forecasting. It is able to capture spatial-temporal dependencies through a designed spatial-temporal synchronous modeling mechanism.\n\n- Reference Paper:\n  - [Song, C., Lin, Y., Guo, S., & Wan, H. (2020, April). Spatial-temporal synchronous graph convolutional networks: A new framework for spatial-temporal network data forecasting.](https://ojs.aaai.org/index.php/AAAI/article/view/5438)\n- Reference Implementation:\n  - [Github repository (Davidham3)](https://github.com/Davidham3/STSGCN)\n\n### XGBoost\n\nXGBoost is a gradient boosting machine learning algorithm widely used in flow prediction and other machine learning prediction areas.\n\n- Reference Paper:\n  - [Alajali, W., Zhou, W., Wen, S., & Wang, Y. (2018). Intersection Traffic Prediction Using Decision Tree Models](https://www.mdpi.com/2073-8994/10/9/386)\n- Reference Package: `xgboost`\n\n## Quick Start\n\n### Quick start with STMeta\n\n```python\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import STMeta\nfrom UCTB.evaluation import metric\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n# Config data loader\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', graph='Correlation',\n                                closeness_len=6, period_len=7, trend_len=4, normalize=True)\n\n# Build Graph\ngraph_obj = GraphGenerator(graph='Correlation', data_loader=data_loader)\n\n# Init model object\nSTMeta_Obj = STMeta(closeness_len=data_loader.closeness_len,\n                    period_len=data_loader.period_len,\n                    trend_len=data_loader.trend_len,\n                    num_node=data_loader.station_number,\n                    num_graph=graph_obj.LM.shape[0],\n                    external_dim=data_loader.external_dim)\n\n# Build tf-graph\nSTMeta_Obj.build()\n# Training\nSTMeta_Obj.fit(closeness_feature=data_loader.train_closeness,\n               period_feature=data_loader.train_period,\n               trend_feature=data_loader.train_trend,\n               laplace_matrix=graph_obj.LM,\n               target=data_loader.train_y,\n               external_feature=data_loader.train_ef,\n               sequence_length=data_loader.train_sequence_len)\n\n# Predict\nprediction = STMeta_Obj.predict(closeness_feature=data_loader.test_closeness,\n                                period_feature=data_loader.test_period,\n                                trend_feature=data_loader.test_trend,\n                                laplace_matrix=graph_obj.LM,\n                                target=data_loader.test_y,\n                                external_feature=data_loader.test_ef,\n                                output_names=['prediction'],\n                                sequence_length=data_loader.test_sequence_len)\n\n# Evaluate\nprint('Test result', metric.rmse(prediction=data_loader.normalizer.min_max_denormal(prediction['prediction']),\n                                 target=data_loader.normalizer.min_max_denormal(data_loader.test_y)))\n```\n\n### Quick Start with HM\n\n```python\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import HM\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=1, period_len=1, trend_len=2,\n                                with_lm=False, normalize=False)\n\nhm_obj = HM(c=data_loader.closeness_len, p=data_loader.period_len, t=data_loader.trend_len)\n\nprediction = hm_obj.predict(closeness_feature=data_loader.test_closeness,\n                            period_feature=data_loader.test_period,\n                            trend_feature=data_loader.test_trend)\n\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))\n```\n\n### Quick Start with ARIMA\n\n```python\nimport numpy as np\n\nfrom UCTB.model import ARIMA\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=24, period_len=0, trend_len=0,\n                                with_lm=False, normalize=False)\n\ntest_prediction_collector = []\nfor i in range(data_loader.station_number):\n    try:\n        model_obj = ARIMA(time_sequence=data_loader.train_closeness[:, i, -1, 0],\n                          order=[6, 0, 1], seasonal_order=[0, 0, 0, 0])\n        test_prediction = model_obj.predict(time_sequences=data_loader.test_closeness[:, i, :, 0],\n                                            forecast_step=1)\n    except Exception as e:\n        print('Converge failed with error', e)\n        print('Using last as prediction')\n        test_prediction = data_loader.test_closeness[:, i, -1:, :]\n    test_prediction_collector.append(test_prediction)\n    print('Station', i, 'finished')\n\ntest_rmse = metric.rmse(np.concatenate(test_prediction_collector, axis=-2), data_loader.test_y)\n\nprint('test_rmse', test_rmse)\n```\n\n### Quick Start with HMM\n\n```python\nimport numpy as np\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import HMM\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC',\n                                closeness_len=12, period_len=0, trend_len=0,\n                                with_lm=False, normalize=False)\n\nprediction = []\nfor station_index in range(data_loader.station_number):\n    # train the hmm model\n    try:\n        hmm = HMM(num_components=8, n_iter=100)\n        hmm.fit(data_loader.train_closeness[:, station_index:station_index+1, -1, 0])\n        # predict\n        p = []\n        for time_index in range(data_loader.test_closeness.shape[0]):\n            p.append(hmm.predict(data_loader.test_closeness[time_index, station_index, :, :], length=1))\n    except Exception as e:\n        print('Failed at station', station_index, 'with error', e)\n        # using zero as prediction\n        p = [[[0]] for _ in range(data_loader.test_closeness.shape[0])]\n\n    prediction.append(np.array(p)[:, :, 0])\n    print('Node', station_index, 'finished')\n\nprediction = np.array(prediction).transpose([1, 0, 2])\nprint('RMSE', metric.rmse(prediction, data_loader.test_y))\n```\n\n### Quick Start with XGBoost\n\n```python\nimport numpy as np\n\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model import XGBoost\nfrom UCTB.evaluation import metric\n\ndata_loader = NodeTrafficLoader(dataset='Bike', city='NYC', closeness_len=6, period_len=7, trend_len=4,\n                                with_lm=False, normalize=False)\n\nprediction_test = []\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = XGBoost(n_estimators=100, max_depth=3, objective='reg:squarederror')\n\n    model.fit(np.concatenate((data_loader.train_closeness[:, i, :, 0],\n                              data_loader.train_period[:, i, :, 0],\n                              data_loader.train_trend[:, i, :, 0],), axis=-1),\n              data_loader.train_y[:, i, 0])\n\n    p_test = model.predict(np.concatenate((data_loader.test_closeness[:, i, :, 0],\n                                           data_loader.test_period[:, i, :, 0],\n                                           data_loader.test_trend[:, i, :, 0],), axis=-1))\n\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\n\nprediction_test = np.concatenate(prediction_test, axis=-2)\n\nprint('Test RMSE', metric.rmse(prediction_test, data_loader.test_y))\n```\n\n## Tutorial\n\nThe general process of completing a spatiotemporal prediction task includes: loading dataset, defining model, training, testing, model evaluation.\n\n![tutorial](https://uctb.github.io/UCTB/sphinx/md_file/src/image/tutorial.png)\n\n### Load datasets from Urban_dataset\n\nTo help better accuse dataset, UCTB provides data loader APIs `UCTB.dataset.data_loader`, which can be used to preprocess data, including **data division**, **normalization**, and **extract temporal and spatial knowledge**.\n\nIn the following tutorial, we will illustrate how to use `UCTB.dataset.data_loader` APIs to inspect the speed dataset.\n\n```python\nfrom UCTB.dataset.data_loader import NodeTrafficLoader\n```\n\nWe use all(data_range='all') of speed data in METR_LA(Assume that scripts are put under root directory, METR_LA dataset is put under `./data` directory.). Firstly, let's initialize a NodeTrafficLoader object:\n\n```python\ndata_loader = NodeTrafficLoader(city='LA',\n                 data_range='all',\n                 train_data_length='all',\n                 test_ratio=0.1,\n                 closeness_len=6,\n                 period_len=7,\n                 trend_len=4,\n                 target_length=1,\n                 normalize=False,\n                 data_dir='data',\n                 MergeIndex=1,\n                 MergeWay=\"sum\",dataset='METR',remove=False)\n```\n\n\n\nNodeTrafficLoader is the base class for dataset extracting and processing. Input arguments appeared in constructor above will be explained.\n\n- data range selection\n`*data range = 'all'` means that we choose the whole data as our traffic_data to train, test, and predict.\n\n- data spliting(train set and test set spliting)\n\n`train_data length = 'all'` means that we exploit all of the traffic_data. `'train_test_ratio = 0.1` means we divide the dataset into train and test sets. And the train set to the test set is nine to one.\n\n- normalization\n\n`normalization = False` means that we normalized the dataset through min-max-normalization method. When we input False, we simply do not employ any preprocessing tricks on the dataset.\n\n- data merging\n\n`MergeIndex = 1, MergeWay = 'sum'` means that granularity of raw dataset will not be changed. If we try MergeIndex > 1, we can obtain combination of MergeIndex time slots of data in a way of 'sum' or 'average'.\n\n- multiple time series building(temporal knowledge exploiting)\n\n`closeness_len = 6, period_len=7, trend_len=4, target_length=1` means that we create 3 time series, using former consecutive closeness_len time slots of data as a unit, former every other daily_slots time slots of data as a unit(consisting of period_len piece of data), former every other daily_slots*7 time slots of data as a unit(consisting of trend_len piece of data) respectively.\n\n```python\nprint(data_loader.train_closeness.shape)\nprint(data_loader.train_period.shape)\nprint(data_loader.train_trend.shape)\nprint(data_loader.train_data.shape)\n```\n```\n(22780, 207, 6, 1)\n(22780, 207, 7, 1)\n(22780, 207, 4, 1)\n(30844, 207)\n```\nYou may probably note that the length of train_closeness is 13778 less than that of train_data. It's because we choose the shortest data length among the three series(train_trend) for alignment.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/data_reassemble.png\" style=\"zoom: 10%;\" />\n\nAbove is the visualization of a new time series's construction. In this situation, feature_stride = 3(means sampling interval), feature_step = 3(means how many times we sample).Other time series are just the same situation.\n\nThrough the process in the figure shown above, we can calculate the length of train_trend is $30844-12*24*7*4=22780$, which is the minimum among three time series.\n\n**Operations**\n\n- Denormalization/Normalization\n- Visualization\n- Temporal Knowledge Exploitation\n- Spatial knowledge Exploration\n- Access to raw data\n\n```python\nimport matplotlib.pyplot as plt\nfrom UCTB.preprocess.preprocessor import Normalizer\n\n# without normalization\n\ntarget_node = 5\nplt.plot(data_loader.traffic_data[:,5])\nplt.title('Raw')\nplt.show()\n\n# normalization\n\nnormalizer=Normalizer(data_loader.traffic_data)\nX_normalized = normalizer.min_max_normal(data_loader.traffic_data)\n\n# denormalization\n\nX_denormalized = normalizer.min_max_denormal(X_normalized)\n\nplt.plot(X_normalized[:,5])\nplt.title('Normalized')\nplt.show()\nplt.plot(X_denormalized[:,5])\nplt.title('Denormalized')\nplt.show()\n```\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/Raw_data.png\" alt=\"Raw_data\" style=\"zoom:33%;\" /><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/normalized_data.png\" style=\"zoom:33%;\" /><img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/denormalized_data.png\" style=\"zoom:33%;\" />\n\n```python\n# Nodes' location visualizations\ndata_loader.st_map()\n```\n\nVisualization result is as follows:\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/METR_LA.png\" alt=\"Node location of METR_LA\" style=\"zoom: 50%;\" />\n\n```python\n# data visualization\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nreal_denormed=data_loader.normalizer.min_max_denormal(data_loader.test_y)\nsns.heatmap(real_denormed[:,:,0], cmap='Reds', vmin = -1000, vmax = 4000)\nplt.ylabel(\"Time Slot\")\nplt.xlabel(\"Sensor Node\")\nplt.title(\"Visualization\")\nplt.show()\n```\n\n```python\n# Feature stitching\nX = data_loader.make_concat()\nprint('before concatenate')\nprint('closeness')\nprint(data_loader.train_closeness.shape)\nprint('period')\nprint(data_loader.train_period.shape)\nprint('trend')\nprint(data_loader.train_trend.shape)\nprint('After concatenate')\nprint(X.shape)\n```\n```\nbefore concatenate\ncloseness\n(22780, 207, 6, 1)\nperiod\n(22780, 207, 7, 1)\ntrend\n(22780, 207, 4, 1)\nAfter concatenate\n(22780, 207, 17, 1)\n```\n```python\n# access to raw data\nprint(data_loader.traffic_data[0,0])\n```\n\n```\n64.375\n```\n\n### Model definition, train, test and evaluation\n\nWe use XGBoost interface in UCTB as an example to define a model. Since there are total 207 stations in METR_LA dataset, we define 207 XGBoost models respectively. They are trained and tested in their own iteration related to stations. Finally, when we evaluate our model, we consider the prediction results as a whole and evaluate it against GroundTruth provided by `data_loader` using [RMSE](https://en.wikipedia.org/wiki/Root-mean-square_deviation) metric.\n\n```python\n\nfrom UCTB.evaluation import metric\nfrom UCTB.model import XGBoost\nimport UCTB.evaluation.metric as metric\nprediction_test = []\n\nfor i in range(data_loader.station_number):\n\n    print('*************************************************************')\n    print('Station', i)\n\n    model = XGBoost(n_estimators=100, max_depth=3, objective='reg:squarederror')\n\n    model.fit(np.concatenate((data_loader.train_closeness[:, i, :, 0],\n                              data_loader.train_period[:, i, :, 0],\n                              data_loader.train_trend[:, i, :, 0],), axis=-1),\n              data_loader.train_y[:, i, 0])\n\n    p_test = model.predict(np.concatenate((data_loader.test_closeness[:, i, :, 0],\n                                           data_loader.test_period[:, i, :, 0],\n                                           data_loader.test_trend[:, i, :, 0],), axis=-1))\n\n    prediction_test.append(p_test.reshape([-1, 1, 1]))\n\nprediction_test = np.concatenate(prediction_test, axis=-2)\n\ny_truth = data_loader.normalizer.inverse_transform(data_loader.test_y)\ny_pred = data_loader.normalizer.inverse_transform(prediction_test)\ny_truth = y_truth.reshape([-1,207])\ny_pred = y_pred.reshape([-1,207])\nprint('Test RMSE', metric.rmse(y_pred, y_truth))\nplt.title('XGBoost Result')\nplt.xlabel('Time Slot')\nplt.ylabel('Speed')\nplt.plot(y_pred[:12*24*7,target_node])\nplt.plot(y_truth[:12*24*7,target_node])\nplt.legend(['gt','pred'])\nplt.show()\n```\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/XGBoost_Result.png\" alt=\"XGBoost Result\" style=\"zoom:50%;\" />\n\n```\nTest RMSE 5.549781682961724\n```\n\n### Single vs. Multiple kinds of temporal knowledge\n\n#### Use temporal closeness feature in regression\n\nUCTB provides many classical and popular spatial-temporal predicting models. These models can be used to either predicting series for a single station or all stations. You can find the details in [``UCTB.model``](./static/current_supported_models.html).\n\nThe following example shows how to use a **XGBoost** model to handle a simple time series predicting a problem. We will try to predict the bike demands ``test_y`` of a fixed station ``target_node`` in New York City by checking back the historical demands in recent time slots ``train_closeness``.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom UCTB.model import XGBoost\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\ntarget_node = 233\n```\n\nWhen initializing the loader, we use past ``12`` time slots (timesteps) of closeness as input, ``1`` timestep in the next as output and set the timesteps of other features ``period_len``, ``period_len`` to zero. \n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=12, period_len=0, trend_len=0,\n                                target_length=1, test_ratio=0.2, \n                                normalize=False, with_lm=False, with_tpe=False)\n```\n\nThe well-loaded data contain all ``717`` stations' data. Therefore it is needed to specify the target station by ``target_station``.\n\n```python\nprint(data_loader.train_closeness.shape)\nprint(data_loader.test_closeness.shape)\nprint(data_loader.test_y.shape)\n```\n\n```python\n(2967, 717, 12, 1)\n(745, 717, 12, 1)\n(745, 717, 1)\n```\n\n\n```python\ntrain_x, test_x = data_loader.train_closeness[:, target_node, :, 0], data_loader.test_closeness[:, target_node, :, 0]\ntrain_y = data_loader.train_y[:, target_node,0]\ntest_y = data_loader.test_y[:, target_node, 0]\n```\n\nInspect the shape of data. Here are the all we need for one-station prediction.\n\n\n```python\nprint(train_x.shape)\nprint(train_y.shape)\nprint(test_x.shape)\nprint(test_y.shape)\n```\n\n    (2967, 12)\n    (2967,)\n    (745, 12)\n    (745,)\n\nBuild the XGBoost model.\n\n```python\nmodel = XGBoost(n_estimators=100, max_depth=3, objective='reg:linear')\n```\n\nNow, we can fit the model with the train dataset and make predictions on the test dataset.\n\n```python\nmodel.fit(x=train_x)\npredictions = model.predict(test_x)\n```\n\nWe can evaluate the performance of the model by build-in ``UCTB.evaluation`` APIs.\n\n```python\ntest_rmse = metric.rmse(predictions, test_y)\nprint(test_rmse)\n```\n\n    3.6033132\n\n#### Make full use of closeness, period, and trend features \n\nIn this case, let's take more temporal knowledge related to ``target_node`` into account. We will concatenate factors including ``closeness``, ``period``, and ``trend``, and use **XGBoost** as the predicting model.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom UCTB.model import XGBoost\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.evaluation import metric\n\ntarget_node = 233\n\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=6, period_len=7, trend_len=4,\n                                target_length=1, test_ratio=0.2, \n                                normalize=False, with_lm=False, with_tpe=False)\n\ntrain_closeness = data_loader.train_closeness[:, target_node, :, 0]\ntrain_period = data_loader.train_period[:, target_nodze, :, 0]\ntrain_trend = data_loader.train_trend[:, target_node, :, 0]\ntrain_y = data_loader.train_y[:, target_node, 0]\n\ntest_closeness = data_loader.test_closeness[:, target_node, :, 0]\ntest_period = data_loader.test_period[:, target_node, :, 0]\ntest_trend = data_loader.test_trend[:, target_node, :, 0]\ntest_y = data_loader.test_y[:, target_node, 0]\n\ntrain_X = np.concatenate([train_closeness, train_period, train_trend], axis=-1)\ntest_X = np.concatenate([test_closeness, test_period, test_trend], axis=-1)\n\nprint(train_X.shape)\nprint(train_y.shape)\nprint(test_X.shape)\nprint(test_y.shape)\n\nmodel = XGBoost(n_estimators=100, max_depth=3, objective='reg:linear')\nmodel.fit(train_X, train_y)\npredictions = model.predict(test_X)\nprint('Test RMSE', metric.rmse(predictions, test_y))\n```\n\n    (2307, 17)\n    (2307,)\n    (745, 17)\n    (745,)\n    Test RMSE 3.3267457\n## Advanced Features\n\n### Build your own model using UCTB\n\nUCTB provides extendable APIs to build your own model. Currently, it can support the running of all the ``1.x`` version of **Tensorflow-based** models. In the following tutorial, we will show you how to takes the least efforts to implement a UCTB model.\n\nCommonly, a new model needs to inherit ``BaseModel`` to acquire the features provided by UCTB, such as batch division, early stopping, etc. The necessary components for a subclass of ``BaseModel`` include:\n\n- ``self.__init__()``. Define the model's parameters related to the architecture. You should call the super class's constructor at first.\n- ``self.build()``. Build the architecture here. You should construct the graph at the beginning of this function and call the super class's ``build()`` function at the end.\n- ``self._input``. The ``dict`` used to record the acceptable inputs of the model, whose keys are the parameter names in ``model.fit()`` and ``model.predict()`` and values are the name of related tensors.\n- ``self._output``. The ``dict`` used to record the outputs of the model. You should fill the required keys ``prediction`` and ``loss`` with the names of tensors in your case.\n- ``self._op``. The ``dict`` used to define all the operations for the model. Basic usage for it is to record the **training operation**, for example, the minimizing loss operation of an optimizer. Use key ``train_op`` to record it.\n\nFor more examples, you can refer to the implementations of build-in models in [``UCTB.model``](../UCTB.model.html#uctb-model-package).\n\n\n```python\nfrom UCTB.model_unit import BaseModel\n\nclass MyModel(BaseModel):\n    def __init__(self,\n                 \n                 code_version='0',\n                 model_dir='my_model',\n                 gpu_device='0',\n                ):\n        super(MyModel, self).__init__(code_version=code_version, \n                                      model_dir=model_dir, gpu_device=gpu_device)\n        ...\n        \n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            ...\n            self._input['inputs'] = inputs.name\n            self._input['targets'] = targets.name\n            \n            ...\n            self._output['prediction'] = predictions.name\n            self._output['loss'] = loss.name\n            self._op['train_op'] = train_op.name\n            \n        super(MyModel, self).build(init_vars=init_vars, max_to_keep=5) \n```\n\nNext, in a concrete case, we will realize a **Long short-term memory (LSTM)** model to make the all-station prediction that accepts time series of `717` stations and predict the future of them as a whole. \n\nFor the mechanism of LSTM, you can refer to \n[Gers, F. A., Schmidhuber, J., & Cummins, F. (1999). Learning to forget: Continual prediction with LSTM](https://www.researchgate.net/profile/Felix_Gers/publication/12292425_Learning_to_Forget_Continual_Prediction_with_LSTM/links/5759414608ae9a9c954e84c5/Learning-to-Forget-Continual-Prediction-with-LSTM.pdf).\n\n\n```python\nimport numpy as np\nimport tensorflow as tf\nfrom UCTB.dataset import NodeTrafficLoader\nfrom UCTB.model_unit import BaseModel\nfrom UCTB.preprocess import SplitData\nfrom UCTB.evaluation import metric\n```\n\n\n```python\nclass LSTM(BaseModel):\n    def __init__(self,\n                 num_stations, \n                 num_layers, \n                 num_units, \n                 input_steps, \n                 input_dim,\n                 output_steps,\n                 output_dim,\n                 code_version='0',\n                 model_dir='my_lstm',\n                 gpu_device='0'):\n        super(LSTM, self).__init__(code_version=code_version, \n                                   model_dir=model_dir, gpu_device=gpu_device)\n        self.num_stations = num_stations\n        self.num_layers = num_layers\n        self.num_units = num_units\n        self.input_steps = input_steps\n        self.input_dim = input_dim\n        self.output_steps = output_steps\n        self.output_dim = output_dim\n        \n    def build(self, init_vars=True, max_to_keep=5):\n        with self._graph.as_default():\n            inputs = tf.placeholder(tf.float32, shape=(None, self.num_stations, \n                                                       self.input_steps, self.input_dim))\n            targets = tf.placeholder(tf.float32, shape=(None, self.num_stations,\n                                                       self.output_steps, self.output_dim))\n            # record the inputs of the model\n            self._input['inputs'] = inputs.name\n            self._input['targets'] = targets.name\n\n            inputs = tf.reshape(inputs, (-1, self.input_steps, self.num_stations*self.input_dim))\n            \n            def get_a_cell(num_units):\n                lstm = tf.nn.rnn_cell.BasicLSTMCell(num_units, state_is_tuple=True)\n                return lstm\n            \n            stacked_cells = tf.contrib.rnn.MultiRNNCell([get_a_cell(self.num_units) for _ in range(self.num_layers)], state_is_tuple=True)\n            outputs, final_state = tf.nn.dynamic_rnn(stacked_cells, inputs, dtype=tf.float32)\n            \n            stacked_outputs = tf.reshape(outputs, shape=(-1, self.num_units*self.input_steps))\n            predictions = tf.layers.dense(stacked_outputs, self.output_steps*self.num_stations*self.output_dim)\n            predictions = tf.reshape(predictions, shape=(-1, self.num_stations, self.output_steps, self.output_dim))\n            \n            loss = tf.sqrt(tf.reduce_mean(tf.square(predictions - targets)))\n            train_op = tf.train.AdamOptimizer().minimize(loss)\n            \n            # record the outputs and the operation of the model\n            self._output['prediction'] = predictions.name\n            self._output['loss'] = loss.name\n            self._op['train_op'] = train_op.name\n        \n        # must call super class' function to build \n        super(LSTM, self).build(init_vars=init_vars, max_to_keep=5) \n```\n\nLoad the dataset by loader and transform them into the formats your model accepts. If the loader APIs are not filled your demands, you can inherit loader and wrapper it according to your desires (see [Quickstart](./quickstart.html) for more details).\n\n\n```python\ndata_loader = NodeTrafficLoader(data_range=0.1, dataset='Bike', city='NYC',\n                                closeness_len=6, period_len=0, trend_len=0,\n                                target_length=1, test_ratio=0.2, \n                                normalize=True, with_lm=False, with_tpe=False)\ntrain_y = np.expand_dims(data_loader.train_y, axis=-1)\ntest_y = np.expand_dims(data_loader.test_y, axis=-1)\n```\n\n\n```python\nmodel = LSTM(num_stations=data_loader.station_number, \n             num_layers=2,\n             num_units=512, \n             input_steps=6, \n             input_dim=1, \n             output_steps=1, \n             output_dim=1)\n```\n\n\n```python\nmodel.build()\nprint(model.trainable_vars)  # count the trainble parameters\n```\n\n    6821581\n\nUse your model to training and predicting. ``model.fit()`` method presets lots of useful functions, such as batch division and early stopping. Check them in [``UCTB.model_unit.BaseModel.BaseModel.fit``](../UCTB.model_unit.html#UCTB.model_unit.BaseModel.BaseModel.fit).\n\n\n```python\nmodel.fit(inputs=data_loader.train_closeness,\n          targets=train_y,\n          max_epoch=10,\n          batch_size=64,\n          sequence_length=data_loader.train_sequence_len,\n          validate_ratio=0.1)\n```\n\n    No model found, start training\n    Running Operation ('train_op',)\n    Epoch 0: train_loss 0.016053785 val_loss 0.01606118\n    Epoch 1: train_loss 0.015499311 val_loss 0.015820855\n    Epoch 2: train_loss 0.015298592 val_loss 0.015657894\n    Epoch 3: train_loss 0.015163456 val_loss 0.015559187\n    Epoch 4: train_loss 0.015066812 val_loss 0.015342651\n    Epoch 5: train_loss 0.015016247 val_loss 0.015287879\n    Epoch 6: train_loss 0.014899823 val_loss 0.015249459\n    Epoch 7: train_loss 0.014773054 val_loss 0.015098239\n    Epoch 8: train_loss 0.014655286 val_loss 0.015097916\n    Epoch 9: train_loss 0.014558283 val_loss 0.015108417\n\n```python\npredictions = model.predict(inputs=data_loader.test_closeness, \n                            sequence_length=data_loader.test_sequence_len)\n```\n\nReverse the normalization by ``data_loader`` and evaluate the results:\n\n\n```python\npredictions = data_loader.normalizer.inverse_transform(predictions['prediction'])\ntargets = data_loader.normalizer.inverse_transform(test_y)\nprint('Test result', metric.rmse(prediction=predictions, target=targets))\n```\n\n    Test result 2.9765626570592545\n\nSince we only use a short period of the dataset (``data_range=0.1``) in this toy example, the result looks good compared with the [experiment](./all_results.html#results-on-bike). You can also take a try to test the completed dataset on your model. \n\n### Build your own graph with STMeta\n\nNext, we will use the Top-K graph as an example to illustrate how to build customized graphs in UCTB. All of the code in this section can be found [here](https://anonymous.4open.science/r/561305b5-e65e-46c6-9371-ae76b85109ee/Experiments/CustomizedDemo/).\n\n**Top-K graph**\n\nFirst of all, the customized graphs used in this section is called Top-K graph. We construct the corresponding adjacent graph by marking the point pair that consist of each point and its nearest K points as 1, and the others are marked as 0. Then, we use the adjacent graph to generate the laplacian matrix for input. The hyperparameter K is designed via ad-hoc heuristics. In this demonstration, we chose 23 as the value of K.\n\n**Realize TopK graph analysis module**\n\nTo adopt customized graphs (***e.g.,*** Top-K) in UCTB, you should first build your own analysis class by inheriting `UCTB.preprocess.GraphGenerator class`.\n\nIt is worth noting that the ultimate goal is to generate the member variables: `self.LM` and `self.AM`, which is the input matrix of the graph. In this phase, we need to make the corresponding analytical implementation according to the type of the custom graph passed in.\n\n ```python\n# \"UCTB/preprocess/topKGraph.py\"\nimport heapq\nimport numpy as np\nfrom UCTB.preprocess.GraphGenerator import GraphGenerator\n\n# Define the class: topKGraph\nclass topKGraph(GraphGenerator):  # Init NodeTrafficLoader\n\n    def __init__(self,**kwargs):\n\n        super(topKGraph, self).__init__(**kwargs)\n        \n        for graph_name in kwargs['graph'].split('-'):\n\n# As the basic graph is implemented in GraphGenerator, you only need to implement your own graph function instead of the existing one.\n            if graph_name.lower() == 'topk':\n                lat_lng_list = np.array([[float(e1) for e1 in e[2:4]]\n                                         for e in self.dataset.node_station_info])\n                # Handling\n                AM = self.neighbour_adjacent(lat_lng_list[self.traffic_data_index],\n                                        threshold=int(kwargs['threshold_neighbour']))\n                LM = self.adjacent_to_laplacian(AM)\n\n                if self.AM.shape[0] == 0:  # Make AM\n                    self.AM = np.array([AM], dtype=np.float32)\n                else:\n                    self.AM = np.vstack((self.AM, (AM[np.newaxis, :])))\n\n                if self.LM.shape[0] == 0:  # Make LM\n                    self.LM = np.array([LM], dtype=np.float32)\n                else:\n                    self.LM = np.vstack((self.LM, (LM[np.newaxis, :])))\n\n# Implement the details of building the Top-K graph.\n    def neighbour_adjacent(self, lat_lng_list, threshold):\n        adjacent_matrix = np.zeros([len(lat_lng_list), len(lat_lng_list)])\n        for i in range(len(lat_lng_list)):\n            for j in range(len(lat_lng_list)):\n                adjacent_matrix[i][j] = self.haversine(\n                    lat_lng_list[i][0], lat_lng_list[i][1], lat_lng_list[j][0], lat_lng_list[j][1])\n        dis_matrix = adjacent_matrix.astype(np.float32)\n\n        for i in range(len(dis_matrix)):\n            ind = heapq.nlargest(threshold, range(len(dis_matrix[i])), dis_matrix[i].take)\n            dis_matrix[i] = np.array([0 for _ in range(len(dis_matrix[i]))])\n            dis_matrix[i][ind] = 1\n        adjacent_matrix = (adjacent_matrix == 1).astype(np.float32)\n        return adjacent_matrix\n ```\n\n**Redefine the call statement of the above class**\n\n```python\n# \"UCTB/Experiments/CustomizedDemo/STMeta_Obj_topk.py\"\n\n# Import the Class: topKGraph\nfrom topKGraph import topKGraph\n# Call topKGraph to initialize and generate AM and LM\ngraphBuilder = topKGraph(graph=args['graph'],\n                         data_loader=data_loader,\n                         threshold_distance=args['threshold_distance'],\n                         threshold_correlation=args['threshold_correlation'],\n                         threshold_interaction=args['threshold_interaction'],\n                         threshold_neighbour=args['threshold_neighbour'])\n# ......\n```\n\n**Modify the function call location**\n\nAdd the new graph name when fitting model and then execute it for experiments. [code](https://github.com/uctb/UCTB/blob/master/Experiments/CustomizedDemo/Runner_topk.py)\n\n```python\nos.system('python STMeta_Obj_topk.py -m STMeta_v1.model.yml -d metro_shanghai.data.yml '\n          '-p graph:Distance-Correlation-Line-TopK,MergeIndex:12')\n```\n\nWe conduct experiments on `Metro_Shanghai` dataset and use the [STMeta_V1](https://uctb.github.io/UCTB/md_file/all_results.html#stmeta-version) to model both \"Distance-Correlation-Line\" graph and \"Distance-Correlation-Line-TopK\" and the results are following:\n\n| **Metro: Shanghai** |             Graph              | Test-RMSE |\n| :-----------------: | :----------------------------: | :-------: |\n|      STMeta_V1      |   Distance-Correlation-Line    |  153.17   |\n|      STMeta_V1      | Distance-Correlation-Line-TopK |  140.82   |\n\nThe results show that the performance of STMeta_V1 with the graph \"Distance-Correlation-Line-TopK\" is better than \"Distance-Correlation-Line\" model and the RMSE is reduced by about 12.4%, which validates the effectiveness of the topk graph for spatiotemporal modeling STMeta algorithm.\n\n------\n\n<u>[Back To HomePage](../index.html)</u>\n\n"
  },
  {
    "path": "docs/sphinx/md_file/src/image/README.md",
    "content": "Image resources\n\n"
  },
  {
    "path": "docs/sphinx/md_file/static/stable_test.md",
    "content": "# Stable Test Records\r\n\r\n## DiDi Chengdu\r\n\r\n#### Parameters for building graph\r\n\r\n| Notation |          explanation           | value |\r\n| :------: | :----------------------------: | :---: |\r\n|    TD    |  threshold of distance graph   | 7500m |\r\n|    TI    | threshold of interaction graph |  30   |\r\n|    TC    | threshold of correlation graph | 0.65  |\r\n\r\n#### Parameters for building model\r\n\r\n```json\r\n{\r\n    \"L\": 1,\r\n    \"PT\": 7,\r\n    \"lr\": 5e-05,\r\n    \"TT\": 4,\r\n    \"DenseUnits\": 32,\r\n    \"GALUnits\": 64,\r\n    \"LSTMUnits\": 64,\r\n    \"ESlength\": 500,\r\n    \"patience\": 0.1,\r\n    \"Normalize\": \"True\",\r\n    \"TI\": 30.0,\r\n    \"CT\": 6,\r\n    \"K\": 1,\r\n    \"GALHeads\": 2,\r\n    \"Graph\": \"Distance-Interaction-Correlation\",\r\n    \"GLL\": 1\r\n}\r\n```\r\n\r\n|   实验编号   |   模型版本含义   |         Test-RMSE值          | Test-MAPE |\r\n| :----------: | :--------------: | :--------------------------: | :-------: |\r\n|      1       | STMeta-V2 |           6.98410            |  0.35470  |\r\n|      2       | STMeta-V2 |           7.06971            |  0.36585  |\r\n|      3       | STMeta-V2 |           7.00403            |  0.34867  |\r\n|      4       | STMeta-V2 |           7.04557            |  0.34797  |\r\n|      5       | STMeta-V2 |           7.05717            |  0.36398  |\r\n|      6       | STMeta-V2 |           6.97287            |  0.34735  |\r\n|      7       | STMeta-V2 |           7.03885            |  0.35656  |\r\n|      8       | STMeta-V2 |           7.09894            |  0.36024  |\r\n|      9       | STMeta-V2 |           7.02147            |  0.33930  |\r\n| 均值、标准差 |                  | 均值 7.03252，标准差 0.03865 |           |\r\n|   平均耗时   |                  |          0.5h~1.5h           |           |\r\n\r\n## DiDi Xian\r\n\r\n```json\r\n{\r\n    \"TrainDays\": \"All\",\r\n    \"DenseUnits\": 32,\r\n    \"GALUnits\": 64,\r\n    \"Graph\": \"Distance-Interaction-Correlation\",\r\n    \"CT\": 6,\r\n    \"Train\": \"False\",\r\n    \"Dataset\": \"DiDi\",\r\n    \"GLL\": 1,\r\n    \"TD\": 7500.0,\r\n    \"GALHeads\": 2,\r\n    \"patience\": 0.1,\r\n    \"Epoch\": 10000,\r\n    \"CodeVersion\": \"ST0\",\r\n    \"TT\": 4,\r\n    \"TC\": 0.65,\r\n    \"Device\": \"1\",\r\n    \"L\": 1,\r\n    \"PT\": 7,\r\n    \"ESlength\": 500,\r\n    \"LSTMUnits\": 64,\r\n    \"TI\": 30.0,\r\n    \"Normalize\": \"True\",\r\n    \"City\": \"Xian\",\r\n    \"lr\": 5e-05,\r\n    \"DataRange\": \"All\",\r\n    \"BatchSize\": 128,\r\n    \"K\": 1,\r\n    \"Group\": \"Xian\"\r\n}\r\n```\r\n\r\nSTMeta-V2 多次实验结果，每次实验耗时 0.5h~1.5h\r\n\r\n| 实验编号 | Test-RMSE | Test-MAPE |\r\n| :------: | :-------: | :-------: |\r\n|    1     |  5.80502  |  0.36022  |\r\n|    2     |  5.88970  |  0.35590  |\r\n|    3     |  6.00412  |  0.45126  |\r\n|    4     |  5.93798  |  0.37956  |\r\n|    5     |  6.01064  |  0.39242  |\r\n|    6     |  5.89309  |  0.40803  |\r\n|    7     |  5.84786  |  0.35915  |\r\n|    8     |  5.88188  |  0.36777  |\r\n|    9     |  5.97407  |  0.42393  |\r\n|    10    |  5.80497  |  0.37014  |\r\n\r\n最终结果：Test-RMSE 均值 5.90493，标准差 0.07142\r\n\r\nMetro Shanghai\r\n\r\n```json\r\n{\r\n    \"TrainDays\": \"All\",\r\n    \"patience\": 0.1,\r\n    \"Train\": \"False\",\r\n    \"TT\": 4,\r\n    \"City\": \"ShanghaiV1\",\r\n    \"ESlength\": 500,\r\n    \"K\": 1,\r\n    \"GLL\": 1,\r\n    \"LSTMUnits\": 64,\r\n    \"Normalize\": \"True\",\r\n    \"PT\": 7,\r\n    \"Epoch\": 10000,\r\n    \"GALUnits\": 64,\r\n    \"TI\": 100.0,\r\n    \"lr\": 2e-05,\r\n    \"Dataset\": \"Metro\",\r\n    \"DenseUnits\": 32,\r\n    \"L\": 1,\r\n    \"Group\": \"Shanghai\",\r\n    \"Graph\": \"Distance-line-Correlation\",\r\n    \"DataRange\": \"All\",\r\n    \"GALHeads\": 2,\r\n    \"CodeVersion\": \"ST_Sim_0\",\r\n    \"CT\": 6,\r\n    \"TD\": 5000.0,\r\n    \"TC\": 0.7,\r\n    \"BatchSize\": 128,\r\n    \"Device\": \"1\"\r\n}\r\n```\r\n\r\nSTMeta-V2 多次实验结果，每次实验耗时 6.5h~7.5h\r\n\r\n| 实验编号 | Test-RMSE | Test-MAPE |\r\n| :------: | :-------: | :-------: |\r\n|    1     | 148.88104 |  0.13178  |\r\n|    2     | 149.58350 |  0.14325  |\r\n|    3     | 168.16162 |  0.14498  |\r\n|    4     | 155.88750 |  0.19575  |\r\n|    5     | 155.09171 |  0.18060  |\r\n|    6     | 166.13303 |  0.18040  |\r\n|    7     | 157.08799 |  0.15245  |\r\n\r\n最终结果：Test-RMSE 均值 157.26091，标准差 6.90058\r\n\r\n## ChargeStation Beijing\r\n\r\n```json\r\n{\r\n    \"GALUnits\": 64,\r\n    \"TD\": 1000.0,\r\n    \"TI\": 500.0,\r\n    \"K\": 1,\r\n    \"Train\": \"False\",\r\n    \"CT\": 6,\r\n    \"patience\": 0.1,\r\n    \"ESlength\": 200,\r\n    \"Graph\": \"Distance-Correlation\",\r\n    \"Normalize\": \"True\",\r\n    \"lr\": 2e-05,\r\n    \"Device\": \"0\",\r\n    \"BatchSize\": 128,\r\n    \"LSTMUnits\": 64,\r\n    \"City\": \"Beijing\",\r\n    \"TrainDays\": \"All\",\r\n    \"CodeVersion\": \"ST_Sim1_0\",\r\n    \"TT\": 4,\r\n    \"GALHeads\": 2,\r\n    \"DenseUnits\": 32,\r\n    \"PT\": 7,\r\n    \"Group\": \"Beijing\",\r\n    \"L\": 1,\r\n    \"DataRange\": \"All\",\r\n    \"TC\": 0.1,\r\n    \"Epoch\": 10000,\r\n    \"Dataset\": \"ChargeStation\",\r\n    \"GLL\": 1\r\n}\r\n```\r\n\r\nSTMeta-V2 多次实验结果 (暂时只跑了4次)，每次实验耗时约 10h\r\n\r\n| 实验编号 | Test-RMSE | Test-MAPE |\r\n| :------: | :-------: | :-------: |\r\n|    1     |  0.80954  |  0.22925  |\r\n|    2     |  0.82956  |  0.23242  |\r\n|    3     |  0.82393  |  0.22467  |\r\n|    4     |  0.81360  |  0.22932  |\r\n\r\n最终结果：Test-RMSE 均值 0.81915，标准差 0.0079745\r\n\r\n"
  },
  {
    "path": "docs/sphinx/md_file/static/transfer_record.md",
    "content": "## Check-In与POI数据处理方法\n\n#### 数据详情\n\n1. 时间范围：Apr 2012 ~ Sept 2013\n\n2. 三个城市的POI数量与check-in数量\n\n   |  城市   | POI数量(计算城市中心为原点、半径为50km的POI数量) | 日均check-in数量(粗略计算所有站点附近1km的checkin数量总和) |\n   | :-----: | :----------------------------------------------: | :--------------------------------------------------------: |\n   |   NYC   |                      71310                       |                  工作日11707，节假日11358                  |\n   | Chicago |                      21949                       |                   工作日2549，节假日2692                   |\n   |   DC    |                      21087                       |                   工作日6049，节假日5450                   |\n\n#### Check-In 特征计算方法\n\n计算 2013-07-15 到 2013-09-15 之间，各个自行车站点附近1km的checkin总数量，按照工作日和节假日分开，即每个站点的特征维度为48，分别为工作日、节假日的24小时checkin\n\n#### POI特征计算方法\n\n一共有428种POI，每个站点统计附近1km出现的POI类型，即每个站点有428维特征\n\n#### 特征相似度方法\n\nCosine Similarity\n\n## 使用Check-In数据进行相似站点的匹配\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|dc|nyc|0.1|1天|5.35244|**5.15155**|8.97297|\n|dc|nyc|0.1|3天|5.35244|**4.83186**|5.60889|\n|dc|nyc|0.1|5天|5.35244|**4.79484**|4.86073|\n|dc|nyc|0.1|7天|5.35244|**4.83927**|5.09481|\n|dc|chicago|0.1|1天|**3.65903**|3.67704|35.02312|\n|dc|chicago|0.1|3天|3.65903|**3.38682**|4.10283|\n|dc|chicago|0.1|5天|3.65903|**3.39081**|3.44701|\n|dc|chicago|0.1|7天|3.65903|**3.16186**|3.36458|\n|chicago|nyc|0.1|1天|7.48254|**6.19588**|8.28328|\n|chicago|nyc|0.1|3天|7.48254|**5.57436**|5.89025|\n|chicago|nyc|0.1|5天|7.48254|**5.54711**|5.64965|\n|chicago|nyc|0.1|7天|7.48254|**5.26407**|6.34057|\n|chicago|dc|0.1|1天|4.32390|**3.87629**|5.78612|\n|chicago|dc|0.1|3天|**4.32390**|4.99620|4.85723|\n|chicago|dc|0.1|5天|4.32390|**3.26380**|3.38408|\n|chicago|dc|0.1|7天|4.32390|**3.15168**|3.27858|\n|nyc|chicago|0.1|1天|5.17356|**4.43069**|12.75022|\n|nyc|chicago|0.1|3天|5.17356|**3.94628**|4.34232|\n|nyc|chicago|0.1|5天|5.17356|**3.93868**|4.52421|\n|nyc|chicago|0.1|7天|5.17356|3.46738|**3.44230**|\n|nyc|dc|0.1|1天|4.11176|**3.58924**|4.46261|\n|nyc|dc|0.1|3天|4.11176|**3.29204**|4.51947|\n|nyc|dc|0.1|5天|4.11176|**3.22782**|3.44588|\n|nyc|dc|0.1|7天|4.11176|**3.09117**|3.17292|\n\n## 使用POI信息进行相似站点匹配\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|dc|nyc|0.1|1天|5.35244|**5.15155**|7.74238|\n|dc|nyc|0.1|3天|5.35244|**4.83186**|5.22502|\n|dc|nyc|0.1|5天|5.35244|**4.79484**|5.14237|\n|dc|nyc|0.1|7天|5.35244|**4.83927**|5.11173|\n|dc|chicago|0.1|1天|**3.65903**|3.67704|42.10733|\n|dc|chicago|0.1|3天|3.65903|**3.38682**|4.01524|\n|dc|chicago|0.1|5天|3.65903|**3.39081**|3.80654|\n|dc|chicago|0.1|7天|3.65903|**3.16186**|3.40228|\n|chicago|nyc|0.1|1天|7.48254|**6.19588**|9.68558|\n|chicago|nyc|0.1|3天|7.48254|**5.57436**|6.06141|\n|chicago|nyc|0.1|5天|7.48254|**5.54711**|5.64207|\n|chicago|nyc|0.1|7天|7.48254|**5.26407**|5.95202|\n|chicago|dc|0.1|1天|4.32390|**3.87629**|7.71124|\n|chicago|dc|0.1|3天|**4.32390**|4.99620|5.20308|\n|chicago|dc|0.1|5天|4.32390|**3.26380**|3.41202|\n|chicago|dc|0.1|7天|4.32390|**3.15168**|3.36520|\n|nyc|chicago|0.1|1天|5.17356|**4.43069**|8.70660|\n|nyc|chicago|0.1|3天|5.17356|**3.94628**|4.68907|\n|nyc|chicago|0.1|5天|5.17356|**3.93868**|4.71885|\n|nyc|chicago|0.1|7天|5.17356|**3.46738**|3.54126|\n|nyc|dc|0.1|1天|4.11176|**3.58924**|4.54878|\n|nyc|dc|0.1|3天|4.11176|**3.29204**|6.51714|\n|nyc|dc|0.1|5天|4.11176|**3.22782**|3.50503|\n|nyc|dc|0.1|7天|4.11176|**3.09117**|3.35844|\n\n|   SD    |   TD    | transfer-ratio | TD-训练样本数量 | TD-Direct |    TD-FT    | TD-Transfer |\n| :-----: | :-----: | :-----: | :-------------: | :-------: | :---------: | :---------: |\n|dc|nyc|0.2|1天|5.35244|**5.15155**|8.01029|\n|dc|nyc|0.2|3天|5.35244|**4.83186**|5.52622|\n|dc|nyc|0.2|5天|5.35244|**4.79484**|5.30417|\n|dc|nyc|0.2|7天|5.35244|**4.83927**|6.07645|\n|dc|nyc|0.2|9天|5.35244|**4.93593**|5.96554|\n|dc|chicago|0.2|1天|**3.65903**|3.67704|46.02469|\n|dc|chicago|0.2|3天|3.65903|**3.38682**|4.22828|\n|dc|chicago|0.2|5天|3.65903|**3.39081**|4.37432|\n|dc|chicago|0.2|7天|3.65903|**3.16186**|3.56052|\n|dc|chicago|0.2|9天|3.65903|**3.12768**|3.39922|\n|nyc|chicago|0.2|1天|5.17356|**4.43069**|11.41116|\n|nyc|chicago|0.2|3天|5.17356|**3.94628**|4.55703|\n|nyc|chicago|0.2|5天|5.17356|**3.93868**|4.31149|\n|nyc|chicago|0.2|7天|5.17356|**3.46738**|3.59811|\n|nyc|chicago|0.2|9天|5.17356|**3.37643**|3.48236|\n|nyc|dc|0.2|1天|4.11176|**3.58924**|5.95973|\n|nyc|dc|0.2|3天|4.11176|**3.29204**|5.09110|\n|nyc|dc|0.2|5天|4.11176|**3.22782**|4.01670|\n|nyc|dc|0.2|7天|4.11176|**3.09117**|3.34005|\n|nyc|dc|0.2|9天|4.11176|**3.02813**|3.31671|\n|chicago|nyc|0.2|1天|7.48254|**6.19588**|9.18276|\n|chicago|nyc|0.2|3天|7.48254|**5.57436**|5.94807|\n|chicago|nyc|0.2|5天|7.48254|**5.54711**|6.02357|\n|chicago|nyc|0.2|7天|7.48254|**5.26407**|6.02906|\n|chicago|nyc|0.2|9天|7.48254|**5.21905**|5.96555|\n|chicago|dc|0.2|1天|4.32390|**3.87629**|5.75511|\n|chicago|dc|0.2|3天|**4.32390**|4.99620|7.56254|\n|chicago|dc|0.2|5天|4.32390|**3.26380**|4.44143|\n|chicago|dc|0.2|7天|4.32390|**3.15168**|3.65643|\n|chicago|dc|0.2|9天|4.32390|**3.13602**|3.25901|\n\n## 分析Transfer效果在城市中的分布\n\n绿色的点表示transfer效果好于finetune，红色代表差于finetune\n\n#### Target City DC\n\n左侧为 Chicago=>DC，Overall result ：Finetune 3.13602，Transfer 3.25901\n\n右侧为 NYC=>DC，Overall result ：Finetune 3.02813，Transfer 3.31671\n\n![1567254312266](..\\src\\image\\transfer_dc.png)\n\n#### Target City NYC\n\n左侧为 DC => NYC，Overall result ：Finetune 4.93593，Transfer 5.96554\n\n右侧为 Chicago =>NYC，Overall result ：Finetune 5.21905，Transfer 5.96555\n\n![1567253682671](..\\src\\image\\transfer_nyc.png)\n\n#### Target City Chicago\n\n左侧为 NYC=>Chicago，Overall result ：Finetune 3.37643，Transfer 3.48236\n\n右侧为 DC=>Chicago，Overall result ：Finetune 3.12768，Transfer 3.39922\n\n![1567255183794](..\\src\\image\\transfer_chicago.png)"
  },
  {
    "path": "docs/sphinx/md_file/uctb_group.md",
    "content": "## About us (UCTB Group)\n\n### PI\n\n**Leye Wang**  \n\n```From Feb 2019, till now.```\n\nAssistant professor @ Key Lab of High Confidence Software Technologies, Department of Computer Science & Technology, Peking University.\n\nEmail: [leyewang@pku.edu.cn](mailto:leyewang@pku.edu.cn) \n\n[Leye Wang's HomePage](https://cs.pku.edu.cn/info/1174/2334.htm)\n\n______\n\n**Longbiao Chen**  \n\n```From March 2022, till now.```\n\nAssociate professor @ Department of Computer Science, Xiamen University, China\n\nEmail: [longbiaochen@xmu.edu.cn](mailto:longbiaochen@xmu.edu.cn) \n\n[Longbiao Chen's HomePage](https://longbiao.crowdsensing.cn/)\n\n### Key Contributors\n\n**Di Chai** (active)\n\n```From Feb 2019, till now.```\n\nPh.D student in computer science and engineering at Hong Kong University of Science and Technology.\n\nEmail: dchai@cse.ust.hk\n\n______\n\n**Liyue Chen** (active)\n\n```From Nov 2019, till now.```\n\nPh.D student in Peking University.\n\nEmail:  chenliyue2019@gmail.com\n\n------\n\n**Jiangyi Fang** (active)\n\n```From April 2022, till now.```\n\nUndergraduate student majored in Automation in Huazhong University of Science and Technology.\n\nEmail:  fangjiangyi2001@gmail.com\n\n------\n\n**Yayao Hong** (active)\n\n```From Sep 2022, till now.```\n\nMaster student in Fujian Key Laboratory of Sensing and Computing for Smart Cities at Xiamen University.\n\nEmail:  hyymmmint@stu.xmu.edu.cn\n\n------\n\n**Tengfei Liu** (active)\n\n```From March 2023, till now.```\n\nUndergraduate student in computer science and technology at China University of Geosciences.\n\nEmail:  tf66366@cug.edu.cn\n\n------\n**Xiuhuai Xie** (active)\n\n```From July 2023, till now.```\n\nPostgraduate student majored in Computer Technology in Xiamen University.\nEmail: trafalgar2001@163.com\n\n### Past Contributors\n\n**Hang Zhu**\n\n```From March 2022, Jul 2023.```\n\nMaster student in Fujian Key Laboratory of Sensing and Computing for Smart Cities at Xiamen University.\n\nEmail:  zhuhang@stu.xmu.edu.cn\n\n------\n\n**Jin Xu**\n\n```From Jul 2019 to Aug 2019.```\n\nUndergraduate student in Peking University majoring in Data Science and Big Data Technology.\n\nEmail: jinxu@pku.edu.cn\n\n______\n\n**Wenjie Yang**\n\n```From Nov 2019 to Aug 2020.```\n\nMaster student in computer science and engineering at Hong Kong University of Science and Technology.\n\nEmail: wjyccs@gmail.com\n\n______\n\n**Xueqiao Xu**\n\n```From Jan 2020 to Jul 2020.```\n\nHe got his bachelor' degree in Peking University majoring in Data Science and Big Data Technology.\n\nEmail:  snowbridge@foxmail.com\n\n------\n\n**Zhenyu Cui**\n\n```From May 2020 to Nov 2020.```\n\nGraduate student in University of Chinese Academy of Sciences, majoring in Computer Vision and Deep Learning.\n\nEmail:  cuizhenyu18@mails.ucas.ac.cn\n"
  },
  {
    "path": "docs/sphinx/md_file/urban_dataset.md",
    "content": "# Urban Datasets\n\nUCTB is designed for urban computing in various scenarios. Currently, It releases [a public dataset repository](https://github.com/uctb/Urban-Dataset) including bike sharing, ride sharing, traffic speed, and pedestrian counting applications. **If you are interested in this project, making a contribution to the dataset is strongly welcomed :)**\n\n## Datasets Overview\n\nCurrently, UCTB offers the following datasets in 7 scenarios, with detailed information provided in the table below. We are constantly working to release more datasets in the future.\n\n| **Application**  |        **City**        |     **Time Range**     | **Temporal Granularity** |                                                      **Dataset Link**                                                       |\n|:----------------:|:----------------------:|:----------------------:|:------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|\n|   Bike-sharing   |          NYC           | 2013.07.01-2017.09.30  |        5 minutes         |            [66.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_NYC.zip)             | \n|   Bike-sharing   |        Chicago         | 2013.07.01-2017.09.30  |        5 minutes         |          [30.2M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_Chicago.zip)           | \n|   Bike-sharing   |           DC           | 2013.07.01-2017.09.30  |        5 minutes         |             [31.0M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bike/5_minutes/Bike_DC.zip)             | \n| Pedestrian Count |       Melbourne        | 2021.01.01-2022.11.01  |        60 minutes        | [1.18M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip) |\n|  Vehicle Speed   |           LA           | 2012.03.01-2012.06.28  |        5 minutes         |            [11.8M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/METR_LA.zip)             |\n|  Vehicle Speed   |          BAY           | 2017.01.01-2017.07.01  |        5 minutes         |            [27.9M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Speed/5_minutes/PEMS_BAY.zip)            |\n|   Taxi Demand    |        Chicago         | 2013.01.01-2018.01.01  |        15 minutes        |          [6.1M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|       Bus        |          NYC           | 2022.02.01-2024.01.13  |         60 mins          |             [4.89M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Bus/60_minutes/Bus_NYC.zip)             |\n|      Metro       |          NYC           | 2022.02.01-2023.12.21  |         60 mins          |           [11.3M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Metro/60_minutes/Metro_NYC.zip)           |\n|   Traffic Flow   |         Luzern         | 2015.01.01-2016.01.01  |          3 mins          |            [21M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Flow/3_minutes/Flow_Luzern.zip)            |\n|   Ride-sharing   |  Chicago (community)   | 2013.01.01-2018.01.01  |         15 mins          |          [6.06](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_Chicago.zip)           |\n|   Ride-sharing   | Chicago (census tract) | 2013.01.01-2018.01.01  |         15 mins          |    [10M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/15_minutes/Taxi_fine_grained_Chicago.zip)     |\n|   Ride-sharing   |          NYC           | 2009.01.01-2023.06.01  |          5 mins          |            [36.9M](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Taxi/5_minutes/Taxi_NYC.zip)             |\n\n## Bike Datasets\nThe bike-sharing datasets are collected from U.S. open data portals including New York City (NYC, https://www.citibikenyc.com/system-data), Chicago (CHI, https://www.divvybikes.com/system-data), and DC (https://www.capitalbikeshare.com/system-data). The dataset time span for all three cities is more than four years. The total number of historical flow records is around 49 million, 13 million, and 14 million in NYC, Chicago, and DC, respectively, and each record contains the start station, start time, stop station, stop time, etc.\n\nThe following shows the map visualization of bike stations in NYC, Chicago, and DC.\n\n<div style=\"display: flex;\">\n  <img src=\"https://camo.githubusercontent.com/eb6a2130ac83330fa6e79276f561c3966c79b7cc90b6cba5b79980127faaa316/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f4e59432e6a7067\" alt=\"图片1\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/9bb00c6ffb052701433ec46dfe52e96365014a2aa3eab825dc4f52e319ff3d1d/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f4368696361676f2e6a7067\" alt=\"图片2\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/a57455f9f9ccba9ed12ec57b3d5d805d75f4577278c824834ea429dc844cf976/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f42696b655f44432e6a7067\" alt=\"图片3\" style=\"flex: 1; max-width: 300px; height: auto;\">\n</div>\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Bike/\n\n## Bus Datasets\nThe bus datasets are collected from DATA.NY.GOV: MTA Bus Hourly Ridership. This dataset is provided by the Metropolitan Transportation Authority and is available for public download. It offers bus ridership estimates on an hourly basis by bus route. Data collection started from February 2022 and has been regularly updated. The Bus_NYC dataset includes data up to January 13, 2024. The latest version can be accessed on the website mentioned above. The station info data is downloaded from NYU | Faculty Digital Archive: New York City Bus Routes, Dec 2019. It does not encompass all bus routes. So we discarded the traffic data for bus routes where station information was not found, ultimately retaining 226 bus routes.\nFollowing shows the map-visualization of Bus_NYC datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Bus.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Bus\n\n## Speed Datasets\nThe two traffic speed datasets are widely used in STTP research: METR-LA and PEMS-BAY from Los Angeles (LA) County and Bay Area, respectively. In METR-LA, 207 sensors record highway vehicles’ speeds for four months; In PEMS-BAY, there are 325 sensors for six months. Each sensor can be seen as a station.\n\nFollowing shows the map-visualization of METR-LA and PEMS-BAY.\n<div style=\"display: flex;\">\n  <img src=\"https://camo.githubusercontent.com/7beb63775a5bcd043923b5b749896af2d10358bc30e2c974f07a882e5b70b20a/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f4d4554525f4c412e706e67\" alt=\"图片1\" style=\"flex: 1; max-width: 300px; height: auto; margin-right: 10px;\">\n  <img src=\"https://camo.githubusercontent.com/091bdeb27f8c007a2b19adfe23c48e072d90f157cd033932dbd773cb47c55dad/68747470733a2f2f756374622e6769746875622e696f2f554354422f737068696e782f6d645f66696c652f7372632f696d6167652f50454d535f4241592e706e67\" alt=\"图片2\" style=\"flex: 1; max-width: 300px; height: auto;\">\n</div>\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Speed/\n\n## Pedestrian Datasets\nThe pedestrian datasets are collected from open data website of Melbourne. The full datasets' timespan is over 10 years and the datasets are still being updated at a fixed frequency (i.e., 60 minutes). Due to the fact that some sites were not set up in the early days and some sites lacked data, we only choose about a year in temporal dimension and 55 stations in spatial dimension. There is also accessible information about sensors on the same website. In the dataset of sensor information, we obtain the name, the sensor's ID, the sensor's status(whether it is active or not), the latitude and longtitude of each sensor.\nFollowing shows the map-visualization of Pedestrian datasets in Melbourne.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Pedestrain_Melbourne.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Pedestrian\n\n## Taxi Datasets\nThe Taxi datasets are collected from the city of Chicago's open data portal and the city of New York's open data portal, where you are able to freely download Chicago city's and NYC's datasets for your own analysis. The datasets record taxi trips from these dimensions listed below: pickup and dropoff time, pickup and dropoff location, fee etc. In our dataset, we only consider the pickup info of each record. You can conduct more comprehensive analysis with the help of our datasets and the website.\n\nTaxi Chicago Dataset\nFacts in dataset description\n\nThere are two candidate spatial discretization information: census tract and community area.\nFor each record, it will aggregate census tract granularity into community area due to privacy preserve.\nWhich granularity to choose\n\nThus, we need to choose a proper granularity. According to the needs of downstream tasks (Spatio-temporal traffic prediction), we summarize two principles of spatial granularity selection:\n\nSpatial granularity as small as possible (especially in high-demand area).\nDemamd aggregated due to privacy as few as possible.\nOn one hand, time distribution of taxi demand in downtown is dense, and the probability of being aggregated is small. on the other hand, the time distribution of taxi demand in the suburbs is sparse, and the probability of being aggregated is high.\n\nFinal datasets we open\n\nWe finally choose to process two datasets: one is Taxi_Chicago, where only spatial granularity community area is used; another is Taxi_fine_grained_Chicago, where community area is used in suburbs while census tract is used in downtown.\n\nWe highly recommend that you conduct more analysis on Taxi_fine_grained_Chicago. By the way, we have adopted a special operation that taxi demand of specific census tract in 15-minute time window equal or less than 2 will be set 2. This operation won't affect much because all of aggregation situation is ultimately caused by insufficient demand.\n\nFollowing shows the map-visualization of Taxi_Chicago datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Chicago_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nFollowing shows the map-visualization of Taxi_fine_grained_Chicago datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Chicago_fine_grained_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nTaxi NYC Datasets\nWe collect Taxi NYC dataset from these two websites: https://opendata.cityofnewyork.us/ and https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page. We also obtain information of taxi zones in New York from this website. As a result of size of dataset, we put it on the link with extraction code gw6p.\n\nFollowing shows the map-visualization of Taxi_NYC datasets.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Taxi.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Taxi\n\n## Metro Datasets\nThe metro datasets are collected from DATA.NY.GOV: MTA Subway Hourly Ridership. The Metro_NYC dataset is provided by the Metropolitan Transportation Authority and is available for public download. It offers estimates of subway ridership on an hourly basis by subway station complex. Data collection started from February 2022 and has been regularly updated. The Metro_NYC dataset includes data up to December 21, 2023. The latest version can be accessed on the website mentioned above.\n\nFollowing shows the map-visualization of station complex in NYC.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/NYC_Metro.png\" alt=\"Image\" style=\"max-width: 300px; height: auto;\">\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Metro\n\n## Flow Speed Datasets\nThe traffic flow datasets are collected from UTD19 - Research Collection. UTD19 is a large-scale traffic data set from over 20000 stationary detectors on urban roads in 40 cities worldwide making it the largest multi-city traffic data set publically available. In our dataset, we only consider the data for the city of Luzern. The dataset enriched location information of sensors with further attributes describing the location of the sensor with respect to the road network.\nFollowing shows the map-visualization of station complex in Luzern.\n\n<img src=\"https://github.com/uctb/Urban-Dataset/raw/main/images/Luzern_Flow.png\" alt=\"Image\" style=\"max-width: 400px; height: auto;\">\n\n\nData catalog: https://github.com/uctb/Urban-Dataset/tree/main/Public_Datasets/Flow\n\n## Load UCTB Dataset\n\n<!-- TODO: 介绍pickle -->\nThe `pickle` module is an external library that comes built-in with Python and provides functionality for converting Python objects into a byte stream (serialization) and restoring them back to their original state (deserialization). We use it to help data format instances to transform between memory and disk.\n\n### Dataset format\n\nWe've collected some public datasets and processing them into UCTB dataset format. UCTB dataset is a python build-in dictionary object that could be loaded by pickle package. Here is the example of UCTB dataset. \n\n```python\n# Let's say ``my_dataset`` is your dataset.\nmy_dataset = {\n    \"TimeRange\": ['YYYY-MM-DD', 'YYYY-MM-DD'],\n    \"TimeFitness\": 60, # Minutes\n    \n    \"Node\": {\n        \"TrafficNode\": np.array, # With shape [time, num-of-node]\n        \"TrafficMonthlyInteraction\": np.array, # With shape [month, num-of-node. num-of-node]\n        \"StationInfo\": list # elements in it should be [id, build-time, lat, lng, name]\n        \"POI\": []\n    },\n\n    \"Grid\": {\n        \"TrafficGrid\": [],\n        \"GridLatLng\": [],\n        \"POI\": []\n    },\n\n    \"ExternalFeature\": {\n         \"Weather\": [time, weather-feature-dim]\n    }\n}\n```\n\n### Use datasets from Urban Datasets\n\nIn this section, we will introduce how to get the dataset from Urban_Dataset and read the dataset using python.\n\nYou are proposed to download the zip file from the [link](https://github.com/uctb/Urban-Dataset/blob/main/Public_Datasets/Pedestrian/60_minutes/Pedestrian_Melbourne.pkl.zip) and unzip the file. Let's say the following scripts are placed at the same directory with the dataset.\n\n```python\nimport pickle as pkl\nimport numpy as np\ndata_path = 'Pedestrian_Melbourne.pkl'\nwith open(data_path,'rb') as fp:\n    data = pkl.load(fp)\n```\n\nTake a look at the necessary information about the dataset:\n\n```python\n# Traffic data \nprint('Data time range', data['TimeRange'])\nprint('Traffic data shape:', np.shape(data['Node']['TrafficNode']))\n# The first dimension of data['Node']['TrafficNode'] is the length of time-sequence.\n# The second dimension is the number of stations.\nprint('Time fitness:', data['TimeFitness'], 'minutes')\nprint('Time sequence length:', data['Node']['TrafficNode'].shape[0])\nprint('Number of stations:', data['Node']['TrafficNode'].shape[1])\n```\n\n    Data time range ['2021-01-01', '2022-11-01']\n    Traffic data shape: (16056, 55)\n    Time fitness: 60 minutes\n    Time sequence length: 16056\n    Number of stations: 55\n\nVisualize the distribution of the traffic data:\n\n```python\nimport matplotlib.pyplot as plt\nplt.plot(data['Node']['TrafficNode'][:, 0])\nplt.show()\n```\n\n![png](src/image/toturial_p1_dataplot.png)\n\n## How to get the datasets at other granularities?\nWe could merge the fine-grained data to obtain the datasets at other granularities (e.g., by summing the 12 flows from the 5-minutes datasets to obtain 60-minutes datasets). UCTB provides the API to merge data. You could specify MergeIndex and MergeWay in the NodeTrafficLoader and GridTrafficLoader. Here is an example:\n```python\nfrom UCTB.dataset import NodeTrafficLoader\n\n# loading 5-minutes datasets\n\ndata_loader = NodeTrafficLoader(dataset=\"Bike\", city=\"NYC\") \nprint(data_loader.dataset.node_traffic.shape) # with shape (446976, 820)\n\ndata_loader = NodeTrafficLoader(dataset=\"Bike\", city=\"NYC\", MergeIndex=12, MergeWay=\"sum\")\nprint(data_loader.dataset.node_traffic.shape) # with shape (37248, 820)\n```\n## Build your own datasets\n\nIf you want to apply uctb dataloaders to your dataset, make your dataset compatible with the template as section 3.2.1 shown. And then save it with package ``pickle`` to a local path ``pkl_file_name``.\n\n```python\nimport pickle\npkl_file_name = './my_dataset.pkl'  \nwith open(pkl_file_name, 'wb') as handle:\n    pickle.dump(my_dataset, handle, protocol=pickle.HIGHEST_PROTOCOL)\n```\n\nFinally, you can make uses of your dataset by UCTB's loader APIs:\n\n```python\ndata_loader = NodeTrafficLoader(dataset=pkl_file_name)\n```\n\nAlso, we provide interface to help build your own dataset, through which we clarify whether a field is necessary or optional when building a UCTB dataset.\n\nTo build a UCTB dataset, it is necessary to provide variables listed as below.\n\n|Variable_name|Description|\n|:--|:--|\n|time_fitness|The length of the interval between adjacent slots|\n|time_range| The time interval at the beginning and end of the data |\n|traffic_node| The spatio-temporal information |\n|node_satation_info| The basic information of each data collecting node |\n|dataset_name| Name of the dataset |\n|city| A variable used to integrate holiday and weather information to traffic data|\n\nThen, use the specified path to save the dataset, otherwise it will be saved in the current run-time path.\n\nAlthough it's diffcult to form an integrated function to include all situation you may meet during the transforming process, there are some procedures you might obey to simplify the data preprocessing.\n\n- Data preprocessing\n    1. Zero values\n    2. Missing values(NA)\n    3. Unknown values\n    4. Abnormal values\n    5. duplicates\n    6. Statistics(station number and time slots)\n- Dictionary building\n    - Basic information(time range and time fitness)\n    - Traffic node building\n        - Spatio-temporal raster data building\n            1. Initialization\n            2. iterate raw data table and fill the matrix\n        - Station information\n    - Traffic grid building\n    - External feature\n\nNow, we assume that you have already finished variable preparation. UCTB provide API to assist you with dataset building.\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago')\n```\n\nAlso, if you want to check what fields are in your datasets, set the argument ``print_dataset`` to ``True``.\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago', print_dataset=True)\n```\n\nOutput:\n\n    dataset[TimeRange]:<class 'list'>  (len=2)\n    dataset[TimeFitness]:<class 'int'>\n    dataset[Node]:<class 'dict'>{\n        dataset[Node][TrafficNode]:<class 'numpy.ndarray'>  (shape=(37248, 532))\n        dataset[Node][StationInfo]:<class 'list'>  (len=(532, 5))\n        dataset[Node][TrafficMonthlyInteraction]:<class 'NoneType'>\n    }\n    dataset[Grid]:<class 'dict'>{\n        dataset[Grid][TrafficGrid]:<class 'NoneType'>\n        dataset[Grid][GridLatLng]:<class 'NoneType'>\n    }\n    dataset[ExternalFeature]:<class 'dict'>{\n        dataset[ExternalFeature][Weather]:<class 'list'>  (len=0)\n    }\n    dataset[LenTimeSlots]:<class 'int'>\n\nWhat's more, if you want to integrate additional information of the dataset, just specify the optional argument as bellow.\n\n|Variable_name|Description|\n|:--|:--|\n|traffic_monthly_interaction| The interactive information among data collecting nodes. |\n|node_poi| Point of interests conformed with node format|\n|grid_poi| Point of interests conformed with grid format|\n|traffic_grid| The spatio-temporal information in grid format. |\n|gird_lat_lng| The basic information of each data collecting grid.|\n|external_feature_weather| The weather information of each day. |\n\nfor example, specify the argument ``external_feature_weather`` with numpy.array object.\n\n```python\nbuild_uctb_dataset(traffic_node=traffic_node, time_fitness=time_fitness, \n                node_station_info=node_station_info, time_range=time_range, \n                output_dir='tmp_dir', dataset_name='dataset', city = 'Chicago', \n                print_dataset=True, external_feature_weather=np.zeros([37248,26]))\n```\n\nThe code above use zero matrix to specify the argument ``external_feature_weather``. While in practical application scenario, you should substitute it with real feather matrix. The first dimension of the matrx is the number of time slots, and the second dimension corresponds to the dimension of weather features."
  },
  {
    "path": "docs/sphinx/md_file/visualization_tool.md",
    "content": "# Visualization-tool\n\nWe have developed a tool that integrates visualization, error localization, and error diagnosis. Specifically, it allows data to be uploaded and provides interactive visual charts to show model errors, combined with spatiotemporal knowledge for error diagnosis. Welcome to visit the [website](http://39.107.116.221/) for a trial.\n\n## Quick Start\n\n### Start with predefined dataset\n\nYou can click on the dropdown menu in the `predefined` module of the `Data Loader`, select the dataset you need, and click `confirm` to obtain the required diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_1.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n### Start with prediction and ground truth\n\nYou can upload specifically formatted TSV files for prediction and ground truth in the `upload` module of the Data Loader. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_2.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n### Start with prediction, ground truth and spatial information\n\nYou can upload specifically formatted TSV files for prediction, ground truth, and spatial information in the `upload` module of the `Data Loader`. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_3.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n###  Start with prediction, ground truth and temporal information\n\nYou can upload specifically formatted TSV files for prediction, and ground truth in the `upload` module of the 'Data Loader', along with the corresponding temporal information. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_4.png\" alt=\"img\" style=\"zoom: 33%;\" />\n\n### Start with prediction, ground truth as well as spatial and temporal information\n\nYou can upload specifically formatted TSV files for prediction, ground truth, and spatial information in the `upload` module of the `Data Loader`, along with the corresponding temporal information. Clicking `confirm` will enable you to obtain the corresponding diagnosis and visualization.\n\n<img src=\"https://uctb.github.io/UCTB/sphinx/md_file/src/image/vis_5.png\" alt=\".img\" style=\"zoom: 33%;\" />\n\n## Contribute to our project.\n\nThe visualization-tool offers two usage options, which are accessing through the [website](http://39.107.116.221/), or using the source code(for contribution).\n\n**Step 1: Requirements**\n\n```vue\nnode == 16.14.0\nnpm == 8.3.1\n```\n\n**Step 2: Clone repository and install dependencies**\n\n```Vue\ngit clone https://github.com/uctb/visualization-tool-UCTB.git \ncd visualization-tool-UCTB \nnpm install\n```\n\n**Step 3: Start**\n\n```Vue\nnpm run serve\n```\n\nThen you will see the following prompt on the screen:\n\n```vue\n App running at:\n  - Local:   http://localhost:xxxx/ \n  - Network: http://ip:xxxx/\n```\n\nYou can customize the visualization tool in the source code to achieve visual effects that better fit the objectives. To better assist you in achieving personalization of the visualization tool, we recommend following these steps to implement it.\n\n**Step 1: Create your own component**\n\n```vue\n<template>\n<div>Your own HTML</div>\n</template>\n\n<script>\nexport default {\n\tname: 'your own component name',\n    data(){}\n}\n</script>\n\n<style scoped>\n /*Your own CSS*/\n</style>\n```\n\n**Step 2: Importing component in App.vue**\n\n```vue\n<script>\nimport YourOwnComponent from \"./components/YourOwnComponent.vue\"\nexport default {\n\tname: 'App',\n    components: {\n     YourOwnComponent\n    }\n}\n</script>\n```\n\nMore instructions on the usage of Vue can be referred to on the [website](https://v2.vuejs.org/). **If you have any interesting or novel ideas, we highly welcome your pull request:)**"
  },
  {
    "path": "docs/sphinx/modules.rst",
    "content": "UCTB\n====\n\n.. toctree::\n   :maxdepth: 4\n\n   UCTB\n"
  },
  {
    "path": "docs/sphinx/update_guide.txt",
    "content": "The first thing is to install the UCTB library, in fact, if you want to update successfully, you must first install the UCTB library successfully。\n\nThe second thing to do is to install the Sphinx-related library functions locally. Here are some of the related versions。\npip install Sphinx==5.1.1\npip install sphinx-markdown-tables==0.0.17\npip install sphinx-rtd-theme==1.2.1\npip install sphinxcontrib-applehelp==1.0.2\npip install sphinxcontrib-devhelp==1.0.2\npip install sphinxcontrib-htmlhelp==2.0.0\npip install sphinxcontrib-jsmath==1.0.1\npip install sphinxcontrib-qthelp==1.0.3\npip install sphinxcontrib-serializinghtml==1.1.5\npip install rtcat-sphinx-theme==0.1.1\npip install recommonmark==0.7.1\npip install commonmark==0.9.1\npip install sphinx-markdown-tables==0.0.17\n\nNext, locate the.md file that corresponds to the section you want to update,\nIf you want to add text, just copy and paste it, if you want to add a big title, you can use the form of a # title, if you want to add a secondary title, you can use the form of a ## title, and so on.\n\nWhen update docstrings, run this code in cmd:\nsphinx-apidoc -o . ../../UCTB\nsphinx-build -b html . ..\nsphinx-build -b html . _build\nThen you can get the html file generated after the update.\n"
  },
  {
    "path": "docs/update_guide.html",
    "content": "\n\n<!DOCTYPE html>\n<!--[if IE 8]><html class=\"no-js lt-ie9\" lang=\"en\" > <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\" > <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>&lt;no title&gt; &mdash; UCTB  documentation</title>\n  \n\n  \n  \n\n  \n\n  \n  \n    \n\n  \n\n  \n  \n    <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  \n\n  \n\n  \n        <link rel=\"index\" title=\"Index\"\n              href=\"genindex.html\"/>\n        <link rel=\"search\" title=\"Search\" href=\"search.html\"/>\n    <link rel=\"top\" title=\"UCTB  documentation\" href=\"index.html\"/> \n\n  \n  <script src=\"_static/js/modernizr.min.js\"></script>\n\n</head>\n\n<body class=\"wy-body-for-nav\" role=\"document\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\">\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> UCTB\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n                <ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/introduction.html\">1. Introduction</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/installation.html\">2. Installation</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/urban_dataset.html\">3. Urban Datasets</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/predictive_tool.html\">4. Predictive Tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/visualization_tool.html\">5. Visualization-tool</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"APIReference.html\">6. API Reference</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/all_results.html\">7. Benchmark</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"md_file/uctb_group.html\">8. About us (UCTB Group)</a></li>\n</ul>\n\n            \n          \n        </div>\n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" role=\"navigation\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">UCTB</a>\n        \n      </nav>\n\n\n      \n      <div class=\"wy-nav-content\">\n        <div class=\"rst-content\">\n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\">Docs</a> &raquo;</li>\n        \n      <li>&lt;no title&gt;</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/update_guide.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <p>The first thing is to install the UCTB library, in fact, if you want to update successfully, you must first install the UCTB library successfully。</p>\n<p>The second thing to do is to install the Sphinx-related library functions locally. Here are some of the related versions。\npip install Sphinx==5.1.1\npip install sphinx-markdown-tables==0.0.17\npip install sphinx-rtd-theme==1.2.1\npip install sphinxcontrib-applehelp==1.0.2\npip install sphinxcontrib-devhelp==1.0.2\npip install sphinxcontrib-htmlhelp==2.0.0\npip install sphinxcontrib-jsmath==1.0.1\npip install sphinxcontrib-qthelp==1.0.3\npip install sphinxcontrib-serializinghtml==1.1.5\npip install rtcat-sphinx-theme==0.1.1\npip install recommonmark==0.7.1\npip install commonmark==0.9.1\npip install sphinx-markdown-tables==0.0.17</p>\n<p>Next, locate the.md file that corresponds to the section you want to update,\nIf you want to add text, just copy and paste it, if you want to add a big title, you can use the form of a # title, if you want to add a secondary title, you can use the form of a ## title, and so on.</p>\n<p>When update docstrings, run this code in cmd:\nsphinx-apidoc -o . ../../UCTB\nsphinx-build -b html . ..\nsphinx-build -b html . _build\nThen you can get the html file generated after the update.</p>\n\n\n           </div>\n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &copy; Copyright 2019, UCTB group.\n\n    </p>\n  </div>\n  Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n\n  \n\n    <script type=\"text/javascript\">\n        var DOCUMENTATION_OPTIONS = {\n            URL_ROOT:'./',\n            VERSION:'',\n            COLLAPSE_INDEX:false,\n            FILE_SUFFIX:'.html',\n            HAS_SOURCE: 'true'\n        };\n    </script>\n      <script type=\"text/javascript\" src=\"_static/jquery.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/underscore.js\"></script>\n      <script type=\"text/javascript\" src=\"_static/doctools.js\"></script>\n      <script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>\n\n  \n\n  \n  \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n  \n\n  \n  \n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.StickyNav.enable();\n      });\n  </script>\n   \n\n</body>\n</html>"
  },
  {
    "path": "environment.yaml",
    "content": "name: UCTB\nchannels:\n  - defaults\ndependencies:\n  - _tflow_select=2.1.0=gpu\n  - absl-py=0.15.0=pyhd3eb1b0_0\n  - astor=0.8.1\n  - blas=1.0=mkl\n  - c-ares=1.18.1\n  - ca-certificates\n  - certifi\n  - cffi=1.14.6\n  - cudatoolkit=10.0.130=0\n  - cudnn=7.6.5=cuda10.0_0\n  - dataclasses=0.8=pyh4f3eec9_6\n  - freetype=2.12.1\n  - gast=0.5.3=pyhd3eb1b0_0\n  - grpcio=1.31.0\n  - h5py=2.9.0\n  - hdf5=1.10.4\n  - importlib-metadata=4.8.1\n  - intel-openmp=2022.1.0\n  - keras=2.2.4=0\n  - keras-applications=1.0.8=py_1\n  - keras-base=2.2.4=py36_0\n  - keras-preprocessing=1.1.2=pyhd3eb1b0_0\n  - lcms2=2.12\n  - lerc=3.0\n  - lz4-c=1.9.4\n  - markdown=3.3.4\n  - mkl=2020.2=256\n  - mkl-service=2.3.0\n  - mkl_fft=1.3.0\n  - mkl_random=1.1.1\n  - mock=4.0.3=pyhd3eb1b0_0\n  - ninja=1.10.2\n  - ninja-base=1.10.2\n  - numpy=1.19\n  - numpy-base=1.19\n  - olefile=0.46=py36_0\n  - openjpeg=2.4.0\n  - openssl=1.1.1t\n  - pillow=8.3.1\n  - pip=21.2.2\n  - protobuf=3.17.2\n  - pycparser=2.21=pyhd3eb1b0_0\n  - python=3.6.13\n  - pyyaml=5.4.1\n  - setuptools=58.0.4\n  - six=1.16.0=pyhd3eb1b0_1\n  - sqlite=3.40.1\n  - tensorboard=1.13.1\n  - tensorflow=1.13.1\n  - tensorflow-base=1.13.1\n  - tensorflow-estimator=1.13.0=py_0\n  - tensorflow-gpu=1.13.1\n  - termcolor=1.1.0\n  - tk=8.6.12\n  - typing_extensions=4.1.1=pyh06a4308_0\n  - werkzeug=2.0.3\n  - wheel=0.37.1\n  - xz=5.2.10\n  - yaml=0.2.5\n  - zipp=3.6.0\n  - zlib=1.2.13\n  - zstd=1.5.2\n  - pytorch=1.1.0\n  - torchvision=0.3.0\n  - pip:\n    - backports-zoneinfo==0.2.1\n    - charset-normalizer==2.0.12\n    - chinese-calendar==1.8.0\n    - chinesecalendar==1.8.0\n    - convertdate==2.3.2\n    - cycler==0.11.0\n    - decorator==4.4.2\n    - gputil==1.4.0\n    - hmmlearn==0.2.8\n    - importlib-resources==5.4.0\n    - joblib==1.1.1\n    - kiwisolver==1.3.1\n    - lunardate==0.2.0\n    - matplotlib==3.3.0\n    - mxnet-cu100==1.5.0\n    - networkx==2.5.1\n    - packaging==21.3\n    - pandas==1.1.5\n    - patsy==0.5.3\n    - pyluach==1.4.2\n    - pymeeus==0.5.12\n    - pyparsing==3.0.9\n    - python-dateutil==2.8.2\n    - pytz==2022.7.1\n    - scikit-learn==0.24.2\n    - smart-open==6.3.0\n    - statsmodels==0.12.2\n    - tensorboardx==2.6\n    - threadpoolctl==3.1.0\n    - wget==3.2\n    - workalendar==16.4.0\n    - xgboost==1.5.2\n    - nni==2.6.1\n    - UCTB==0.3.5"
  },
  {
    "path": "setup.py",
    "content": "import setuptools\n\nwith open(\"README.md\", \"r\") as fh:\n    long_description = fh.read()\n\nsetuptools.setup(\n    name=\"UCTB\",\n    version=\"0.3.5\",\n    author=\"UCTB group\",\n    author_email=\"chenliyue2019@gmail.com\",\n    description=\"Urban Computing ToolBox\",\n    long_description=long_description,\n    long_description_content_type=\"text/markdown\",\n    url=\"https://github.com/uctb/UCTB\",\n    packages=setuptools.find_packages(),\n    install_requires=['hmmlearn>=0.2.1',\n                      'keras==2.2.4',\n                      'GPUtil',\n                      'numpy>=1.16.2',\n                      'pandas>=0.24.2',\n                      'python-dateutil',\n                      'scikit-learn>=0.20.3',\n                      'scipy==1.2.1',\n                      'statsmodels>=0.9.0',\n                      'wget>=3.2',\n                      'xgboost>=0.82',\n                      'nni>=0.8',\n                      'chinesecalendar>=1.2.2',\n                      'workalendar>=8.2.0',\n                      'PyYAML>=5.1.1'],\n    classifiers=[\n        \"Programming Language :: Python :: 3\",\n        \"License :: OSI Approved :: MIT License\",\n        \"Operating System :: OS Independent\",\n    ],\n)"
  }
]